<!DOCTYPE html><html class=split lang=en-US-x-hixie><script src=../link-fixup.js defer=""></script>
<!-- Mirrored from html.spec.whatwg.org/multipage/speculative-loading.html by HTTrack Website Copier/3.x [XR&CO'2014], Wed, 10 Sep 2025 08:35:53 GMT -->
<!-- Added by HTTrack --><meta http-equiv="content-type" content="text/html;charset=utf-8" /><!-- /Added by HTTrack -->
<meta charset=utf-8><meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name=viewport><title>HTML Standard</title><meta content=#3c790a name=theme-color><meta content="light dark" name=color-scheme><link rel=stylesheet href=../../resources.whatwg.org/standard-shared-with-dev.css crossorigin=""><link rel=stylesheet href=../../resources.whatwg.org/standard.css crossorigin=""><link rel=stylesheet href=../../resources.whatwg.org/spec.css crossorigin=""><link rel=icon href=https://resources.whatwg.org/logo.svg crossorigin=""><link rel=stylesheet href=../styles.css crossorigin=""><script>
   function toggleStatus(div) {
     div.parentNode.classList.toggle('wrapped');
   }
   function setLinkFragment(link) {
     link.hash = location.hash;
   }
  </script><body>
  
  <script defer="" crossorigin="" src=../html-dfn.js></script>
  
  <header id=head class="head with-buttons">
   <a href=https://whatwg.org/ class=logo><img width=100 alt=WHATWG crossorigin="" class=darkmode-aware src=https://resources.whatwg.org/logo.svg height=100></a>
   <hgroup><h1 class=allcaps>HTML</h1><p id=living-standard>Living Standard — Last Updated <span class=pubdate>10 September 2025</span></hgroup>
   
   

   
  </header>

  

  

  

  
  

  
  

  

  <nav><a href=document-lifecycle.html>← 7.5 Document lifecycle</a> — <a href=index.html>Table of Contents</a> — <a href=webappapis.html>8 Web application APIs →</a></nav><ol class=toc><li id=toc-browsers><ol><li><a href=speculative-loading.html#speculative-loading><span class=secno>7.6</span> Speculative loading</a><ol><li><a href=speculative-loading.html#speculation-rules><span class=secno>7.6.1</span> Speculation rules</a><ol><li><a href=speculative-loading.html#speculation-rules-data-model><span class=secno>7.6.1.1</span> Data model</a><li><a href=speculative-loading.html#speculation-rules-parsing><span class=secno>7.6.1.2</span> Parsing</a><li><a href=speculative-loading.html#speculation-rules-processing-model><span class=secno>7.6.1.3</span> Processing model</a></ol><li><a href=speculative-loading.html#navigational-prefetching><span class=secno>7.6.2</span> Navigational prefetching</a><li><a href=speculative-loading.html#the-speculation-rules-header><span class=secno>7.6.3</span> The `<code>Speculation-Rules</code>` header</a><li><a href=speculative-loading.html#the-sec-speculation-tags-header><span class=secno>7.6.4</span> The `<code>Sec-Speculation-Tags</code>` header</a><li><a href=speculative-loading.html#speculative-loading-security><span class=secno>7.6.5</span> Security considerations</a><ol><li><a href=speculative-loading.html#speculative-loading-cross-site-requests><span class=secno>7.6.5.1</span> Cross-site requests</a><li><a href=speculative-loading.html#speculative-loading-injected-content><span class=secno>7.6.5.2</span> Injected content</a><li><a href=speculative-loading.html#speculative-loading-ip-anonymization><span class=secno>7.6.5.3</span> IP anonymization</a></ol><li><a href=speculative-loading.html#speculative-loading-privacy><span class=secno>7.6.6</span> Privacy considerations</a><ol><li><a href=speculative-loading.html#speculative-loading-heuristics><span class=secno>7.6.6.1</span> Heuristics and optionality</a><li><a href=speculative-loading.html#speculative-loading-state-partitioning><span class=secno>7.6.6.2</span> State partitioning</a><li><a href=speculative-loading.html#speculative-loading-identity-joining><span class=secno>7.6.6.3</span> Identity joining</a></ol></ol><li><a href=speculative-loading.html#the-x-frame-options-header><span class=secno>7.7</span> The `<code>X-Frame-Options</code>` header</a><li><a href=speculative-loading.html#the-refresh-header><span class=secno>7.8</span> The `<code>Refresh</code>` header</a><li><a href=speculative-loading.html#nav-traversal-ui><span class=secno>7.9</span> Browser user interface
  considerations</a></ol></ol><h3 id=speculative-loading><span class=secno>7.6</span> Speculative loading<a href=#speculative-loading class=self-link></a></h3>

  <p>Speculative loading is the practice of performing navigation actions, such as prefetching,
  ahead of navigation starting. This makes subsequent navigations faster.</p>

  <p>Developers can initiate speculative loads by using <a href=#speculation-rule-set id=speculative-loading:speculation-rule-set>speculation rules</a>. User agents might also perform speculative loads in certain
  <a id=speculative-loading:implementation-defined href=https://infra.spec.whatwg.org/#implementation-defined data-x-internal=implementation-defined>implementation-defined</a> scenarios, such as typing into the address bar.</p>

  <h4 id=speculation-rules><span class=secno>7.6.1</span> Speculation rules<a href=#speculation-rules class=self-link></a></h4>

  <p><a href=#speculation-rule-set id=speculation-rules:speculation-rule-set>Speculation rules</a> are how developers instruct the
  browser about speculative loading operations that the developer believes will be beneficial. They
  are delivered as JSON documents, via either:</p>

  <ul><li><p>inline <code id=speculation-rules:the-script-element><a href=scripting.html#the-script-element>script</a></code> elements with their <code id=speculation-rules:attr-script-type><a href=scripting.html#attr-script-type>type</a></code>
   attribute set to "<code>speculationrules</code>"; or<li><p>resources fetched from a URL specified in the `<code id=speculation-rules:speculation-rules-2><a href=#speculation-rules-2>Speculation-Rules</a></code>` HTTP
   response header.</ul>

  <div id=example-speculation-rules-simple class=example><a href=#example-speculation-rules-simple class=self-link></a>
   <p>The following JSON document is parsed into a <a href=#speculation-rule-set id=speculation-rules:speculation-rule-set-2>speculation rule set</a> specifying a
   number of desired conditions for the user agent to <a id=speculation-rules:start-a-referrer-initiated-navigational-prefetch href=https://wicg.github.io/nav-speculation/prefetch.html#start-a-referrer-initiated-navigational-prefetch data-x-internal=start-a-referrer-initiated-navigational-prefetch>start a referrer-initiated navigational
   prefetch</a>:</p>

   <pre><code class='json'><c- p>{</c->
  <c- u>&quot;prefetch&quot;</c-><c- o>:</c-> <c- p>[</c->
    <c- p>{</c->
      <c- u>&quot;urls&quot;</c-><c- o>:</c-> <c- p>[</c-><c- u>&quot;/chapters/5&quot;</c-><c- p>]</c->
    <c- p>},</c->
    <c- p>{</c->
      <c- u>&quot;eagerness&quot;</c-><c- o>:</c-> <c- u>&quot;moderate&quot;</c-><c- p>,</c->
      <c- u>&quot;where&quot;</c-><c- o>:</c-> <c- p>{</c->
        <c- u>&quot;and&quot;</c-><c- o>:</c-> <c- p>[</c->
          <c- p>{</c-> <c- u>&quot;href_matches&quot;</c-><c- o>:</c-> <c- u>&quot;/*&quot;</c-> <c- p>},</c->
          <c- p>{</c-> <c- u>&quot;not&quot;</c-><c- o>:</c-> <c- p>{</c-> <c- u>&quot;selector_matches&quot;</c-><c- o>:</c-> <c- u>&quot;.no-prefetch&quot;</c-> <c- p>}</c-> <c- p>}</c->
        <c- p>]</c->
      <c- p>}</c->
    <c- p>}</c->
  <c- p>]</c->
<c- p>}</c-></code></pre>
  </div>

  <p>A JSON document representing a <a href=#speculation-rule-set id=speculation-rules:speculation-rule-set-3>speculation rule set</a> must meet the following
  <dfn id=speculation-rule-set-authoring-requirements>speculation rule set authoring requirements</dfn>:</p>

  <ul><li><p>It must be valid JSON. <a href=references.html#refsJSON>[JSON]</a><li>
    <p>The JSON must represent a JSON object, with at most three keys "<code>tag</code>",
    "<code>prefetch</code>" and "<code>prerender</code>".</p>

    <p class=note>In this standard, "<code>prerender</code>" is optionally converted to
    "<code>prefetch</code>" <a href=#note-speculation-rules-parse-prerender-as-prefetch>at parse time</a>. Some
    implementations might implement different behavior for prerender, as specified in
    <cite>Prerendering Revamped</cite>. <a href=references.html#refsPRERENDERING-REVAMPED>[PRERENDERING-REVAMPED]</a></p>
   <li><p>The value corresponding to the "<code>tag</code>" key, if present, must be a
   <a href=#speculation-rule-tag id=speculation-rules:speculation-rule-tag>speculation rule tag</a>.<li><p>The values corresponding to the "<code>prefetch</code>" and "<code>prerender</code>" keys, if present, must be arrays of <a href=#valid-speculation-rule id=speculation-rules:valid-speculation-rule>valid speculation rules</a>.</ul>

  <p>A <dfn id=valid-speculation-rule>valid speculation rule</dfn> is a JSON object that meets the following requirements:</p>

  <ul><li>
    <p>It must have at most the following keys: "<code>source</code>", "<code>urls</code>", "<code>where</code>", "<code>relative_to</code>",
    "<code>eagerness</code>",  "<code>referrer_policy</code>", "<code>tag</code>", "<code>requires</code>", "<code>expects_no_vary_search</code>", or "<code>target_hint</code>".</p>

    <p class=note>In this standard, <a href=#note-speculation-rules-parse-target-hint>"<code>target_hint</code>" is ignored</a>.</p>
   <li><p>The value corresponding to the "<code>source</code>" key, if present, must be
   either "<code>list</code>" or "<code>document</code>".<li><p>If the value corresponding to the "<code>source</code>" key is "<code>list</code>", then the "<code>urls</code>" key must be present, and the
   "<code>where</code>" key must be absent.<li><p>If the value corresponding to the "<code>source</code>" key is "<code>document</code>", then the "<code>urls</code>" key must be absent.<li><p>The "<code>urls</code>" and "<code>where</code>" keys must not both be
   present.<li><p>If the value corresponding to the "<code>source</code>" key is "<code>document</code>" or the "<code>where</code>" key is present, then the "<code>relative_to</code>" key must be absent.<li><p>The value corresponding to the "<code>urls</code>" key, if present, must be an
   array of <a href=https://url.spec.whatwg.org/#valid-url-string id=speculation-rules:valid-url-string data-x-internal=valid-url-string>valid URL strings</a>.<li><p>The value corresponding to the "<code>where</code>" key, if present, must be a
   <a href=#valid-document-rule-predicate id=speculation-rules:valid-document-rule-predicate>valid document rule predicate</a>.<li><p>The value corresponding to the "<code>relative_to</code>" key, if present, must
   be either "<code>ruleset</code>" or "<code>document</code>".<li><p>The value corresponding to the "<code>eagerness</code>" key, if present, must be
   a <a href=#speculation-rule-eagerness id=speculation-rules:speculation-rule-eagerness>speculation rule eagerness</a>.<li><p>The value corresponding to the "<code>referrer_policy</code>" key, if present,
   must be a <a id=speculation-rules:referrer-policy href=https://w3c.github.io/webappsec-referrer-policy/#referrer-policy data-x-internal=referrer-policy>referrer policy</a>.<li><p>The value corresponding to the "<code>tag</code>" key, if present, must be a
   <a href=#speculation-rule-tag id=speculation-rules:speculation-rule-tag-2>speculation rule tag</a>.<li><p>The value corresponding to the "<code>requires</code>" key, if present, must be
   an array of <a href=#speculation-rule-requirement id=speculation-rules:speculation-rule-requirement>speculation rule
   requirements</a>.<li><p>The value corresponding to the "<code>expects_no_vary_search</code>" key, if
   present, must be a <a id=speculation-rules:string href=https://infra.spec.whatwg.org/#string data-x-internal=string>string</a> that is <a href=https://httpwg.org/http-extensions/draft-ietf-httpbis-no-vary-search.html#parse-a-url-search-variance id=speculation-rules:parse-a-url-search-variance data-x-internal=parse-a-url-search-variance>parseable</a> as a `<code id=speculation-rules:no-vary-search><a data-x-internal=no-vary-search href=https://httpwg.org/http-extensions/draft-ietf-httpbis-no-vary-search.html#name-http-header-field-definitio>No-Vary-Search</a></code>` header value.</ul>

  <p>A <dfn id=valid-document-rule-predicate>valid document rule predicate</dfn> is a JSON object that meets the following
  requirements:</p>

  <ul><li><p>It must contain exactly one of the keys "<code>and</code>", "<code>or</code>", "<code>not</code>", "<code>href_matches</code>", or
   "<code>selector_matches</code>".<li><p>It must not contain any keys apart from the above or "<code>relative_to</code>".<li><p>If it contains the key "<code>relative_to</code>", then it must also contain the
   key "<code>href_matches</code>".<li><p>The value corresponding to the "<code>relative_to</code>" key, if present, must
   be either "<code>ruleset</code>" or "<code>document</code>".<li><p>The value corresponding to the "<code>and</code>" or "<code>or</code>"
   keys, if present, must be arrays of <a href=#valid-document-rule-predicate id=speculation-rules:valid-document-rule-predicate-2>valid document
   rule predicates</a>.<li><p>The value corresponding to the "<code>not</code>" key, if present, must be a
   <a href=#valid-document-rule-predicate id=speculation-rules:valid-document-rule-predicate-3>valid document rule predicate</a>.<li><p>The value corresponding to the "<code>href_matches</code>" key, if present, must
   be either a <a href=#valid-url-pattern-input id=speculation-rules:valid-url-pattern-input>valid URL pattern input</a> or an array of <a href=#valid-url-pattern-input id=speculation-rules:valid-url-pattern-input-2>valid URL pattern inputs</a>.<li><p>The value corresponding to the "<code>selector_matches</code>" key, if present,
   must be either a <a id=speculation-rules:string-2 href=https://infra.spec.whatwg.org/#string data-x-internal=string>string</a> matching <code id=speculation-rules:selector-list><a data-x-internal=selector-list href=https://drafts.csswg.org/selectors/#typedef-selector-list>&lt;selector-list></a></code> or an array of
   <a href=https://infra.spec.whatwg.org/#string id=speculation-rules:string-3 data-x-internal=string>strings</a> that match <code id=speculation-rules:selector-list-2><a data-x-internal=selector-list href=https://drafts.csswg.org/selectors/#typedef-selector-list>&lt;selector-list></a></code>.</ul>

  <p>A <dfn id=valid-url-pattern-input>valid URL pattern input</dfn> is either:</p>

  <ul><li><p>a <a id=speculation-rules:scalar-value-string href=https://infra.spec.whatwg.org/#scalar-value-string data-x-internal=scalar-value-string>scalar value string</a> that can be successfully <a href=https://urlpattern.spec.whatwg.org/#parse-a-constructor-string id=speculation-rules:parse-a-url-pattern-constructor-string data-x-internal=parse-a-url-pattern-constructor-string>parsed</a> as a URL pattern constructor string, or;<li><p>a JSON object whose keys are drawn from the members of the <code id=speculation-rules:urlpatterninit><a data-x-internal=urlpatterninit href=https://urlpattern.spec.whatwg.org/#dictdef-urlpatterninit>URLPatternInit</a></code>
   dictionary and whose values are <a href=https://infra.spec.whatwg.org/#scalar-value-string id=speculation-rules:scalar-value-string-2 data-x-internal=scalar-value-string>scalar value
   strings</a>.</ul>

  <h5 id=speculation-rules-data-model><span class=secno>7.6.1.1</span> Data model<a href=#speculation-rules-data-model class=self-link></a></h5>

  <p>A <dfn id=speculation-rule-set>speculation rule set</dfn> is a <a id=speculation-rules-data-model:struct href=https://infra.spec.whatwg.org/#struct data-x-internal=struct>struct</a> with the following <a href=https://infra.spec.whatwg.org/#struct-item id=speculation-rules-data-model:struct-item data-x-internal=struct-item>items</a>:</p>

  <ul><li><p><dfn id=sr-set-prefetch>prefetch rules</dfn>, a <a id=speculation-rules-data-model:list href=https://infra.spec.whatwg.org/#list data-x-internal=list>list</a> of <a href=#speculation-rule id=speculation-rules-data-model:speculation-rule>speculation rules</a>, initially empty</ul>

  <p class=note>In the future, other rules will be possible, e.g., prerender rules. See
  <cite>Prerendering Revamped</cite> for such not-yet-accepted extensions.
  <a href=references.html#refsPRERENDERING-REVAMPED>[PRERENDERING-REVAMPED]</a></p>

  <p>A <dfn id=speculation-rule>speculation rule</dfn> is a <a id=speculation-rules-data-model:struct-2 href=https://infra.spec.whatwg.org/#struct data-x-internal=struct>struct</a> with the following <a href=https://infra.spec.whatwg.org/#struct-item id=speculation-rules-data-model:struct-item-2 data-x-internal=struct-item>items</a>:</p>

  <ul><li><p><dfn id=sr-urls>URLs</dfn>, an <a href=https://infra.spec.whatwg.org/#ordered-set id=speculation-rules-data-model:set data-x-internal=set>ordered set</a> of <a href=https://url.spec.whatwg.org/#concept-url id=speculation-rules-data-model:url data-x-internal=url>URLs</a><li><p><dfn id=sr-predicate>predicate</dfn>, a <a href=#document-rule-predicate id=speculation-rules-data-model:document-rule-predicate>document rule predicate</a> or
   null<li><p><dfn id=sr-eagerness>eagerness</dfn>, a <a href=#speculation-rule-eagerness id=speculation-rules-data-model:speculation-rule-eagerness>speculation rule
   eagerness</a><li><p><dfn id=sr-referrer-policy>referrer policy</dfn>, a <a id=speculation-rules-data-model:referrer-policy href=https://w3c.github.io/webappsec-referrer-policy/#referrer-policy data-x-internal=referrer-policy>referrer
   policy</a><li><p><dfn id=sr-tags>tags</dfn>, an <a href=https://infra.spec.whatwg.org/#ordered-set id=speculation-rules-data-model:set-2 data-x-internal=set>ordered set</a> of <a href=#speculation-rule-tag id=speculation-rules-data-model:speculation-rule-tag>speculation rule tags</a><li><p><dfn id=sr-requirements>requirements</dfn>, an <a href=https://infra.spec.whatwg.org/#ordered-set id=speculation-rules-data-model:set-3 data-x-internal=set>ordered set</a>
   of <a href=#speculation-rule-requirement id=speculation-rules-data-model:speculation-rule-requirement>speculation rule requirements</a><li><p><dfn id=sr-nvs-hint>No-Vary-Search hint</dfn>, a <a id=speculation-rules-data-model:url-search-variance href=https://httpwg.org/http-extensions/draft-ietf-httpbis-no-vary-search.html#name-data-model data-x-internal=url-search-variance>URL search
   variance</a></ul>

  <hr>

  <p>A <dfn id=document-rule-predicate>document rule predicate</dfn> is one of the following:</p>

  <ul><li><p>a <a href=#document-rule-conjunction id=speculation-rules-data-model:document-rule-conjunction>document rule conjunction</a>;<li><p>a <a href=#document-rule-disjunction id=speculation-rules-data-model:document-rule-disjunction>document rule disjunction</a>;<li><p>a <a href=#document-rule-negation id=speculation-rules-data-model:document-rule-negation>document rule negation</a>;<li><p>a <a href=#document-rule-url-pattern-predicate id=speculation-rules-data-model:document-rule-url-pattern-predicate>document rule URL pattern predicate</a>; or<li><p>a <a href=#document-rule-selector-predicate id=speculation-rules-data-model:document-rule-selector-predicate>document rule selector predicate</a>.</ul>

  <p>A <dfn id=document-rule-conjunction>document rule conjunction</dfn> is a <a id=speculation-rules-data-model:struct-3 href=https://infra.spec.whatwg.org/#struct data-x-internal=struct>struct</a> with the following <a href=https://infra.spec.whatwg.org/#struct-item id=speculation-rules-data-model:struct-item-3 data-x-internal=struct-item>items</a>:</p>

  <ul><li><p><dfn id=sr-dr-c-clauses>clauses</dfn>, a <a id=speculation-rules-data-model:list-2 href=https://infra.spec.whatwg.org/#list data-x-internal=list>list</a> of <a href=#document-rule-predicate id=speculation-rules-data-model:document-rule-predicate-2>document rule predicates</a></ul>

  <p>A <dfn id=document-rule-disjunction>document rule disjunction</dfn> is a <a id=speculation-rules-data-model:struct-4 href=https://infra.spec.whatwg.org/#struct data-x-internal=struct>struct</a> with the following <a href=https://infra.spec.whatwg.org/#struct-item id=speculation-rules-data-model:struct-item-4 data-x-internal=struct-item>items</a>:</p>

  <ul><li><p><dfn id=sr-dr-d-clauses>clauses</dfn>, a <a id=speculation-rules-data-model:list-3 href=https://infra.spec.whatwg.org/#list data-x-internal=list>list</a> of <a href=#document-rule-predicate id=speculation-rules-data-model:document-rule-predicate-3>document rule predicates</a></ul>

  <p>A <dfn id=document-rule-negation>document rule negation</dfn> is a <a id=speculation-rules-data-model:struct-5 href=https://infra.spec.whatwg.org/#struct data-x-internal=struct>struct</a> with the following <a href=https://infra.spec.whatwg.org/#struct-item id=speculation-rules-data-model:struct-item-5 data-x-internal=struct-item>items</a>:</p>

  <ul><li><p><dfn id=sr-dr-n-clause>clause</dfn>, a <a href=#document-rule-predicate id=speculation-rules-data-model:document-rule-predicate-4>document rule predicate</a></ul>

  <p>A <dfn id=document-rule-url-pattern-predicate>document rule URL pattern predicate</dfn> is a <a id=speculation-rules-data-model:struct-6 href=https://infra.spec.whatwg.org/#struct data-x-internal=struct>struct</a> with the following
  <a href=https://infra.spec.whatwg.org/#struct-item id=speculation-rules-data-model:struct-item-6 data-x-internal=struct-item>items</a>:</p>

  <ul><li><p><dfn id=sr-dr-urlpattern-patterns>patterns</dfn>, a <a id=speculation-rules-data-model:list-4 href=https://infra.spec.whatwg.org/#list data-x-internal=list>list</a> of <a href=https://urlpattern.spec.whatwg.org/#url-pattern id=speculation-rules-data-model:url-pattern data-x-internal=url-pattern>URL patterns</a></ul>

  <p>A <dfn id=document-rule-selector-predicate>document rule selector predicate</dfn> is a <a id=speculation-rules-data-model:struct-7 href=https://infra.spec.whatwg.org/#struct data-x-internal=struct>struct</a> with the following <a href=https://infra.spec.whatwg.org/#struct-item id=speculation-rules-data-model:struct-item-7 data-x-internal=struct-item>items</a>:</p>

  <ul><li><p><dfn id=sr-dr-cssselector-selectors>selectors</dfn>, a <a id=speculation-rules-data-model:list-5 href=https://infra.spec.whatwg.org/#list data-x-internal=list>list</a> of <a href=https://drafts.csswg.org/selectors/#selector id=speculation-rules-data-model:selector data-x-internal=selector>selectors</a></ul>

  <hr>

  <p>A <dfn id=speculation-rule-eagerness>speculation rule eagerness</dfn> is one of the following <a href=https://infra.spec.whatwg.org/#string id=speculation-rules-data-model:string data-x-internal=string>strings</a>:</p>

  <dl><dt>"<dfn id=sr-eagerness-immediate><code>immediate</code></dfn>"<dd><p>The developer believes that performing the associated speculative loads is very likely to
   be worthwhile, and they might also expect that load to require significant lead time to complete.
   User agents should usually enact the speculative load candidate as soon as practical, subject
   only to considerations such as user preferences, device conditions, and resource limits.<dt>"<dfn id=sr-eagerness-eager><code>eager</code></dfn>"<dd><p>User agents should enact the speculative load candidate on even a slight suggestion that
   the user may navigate to this URL in the future. For instance, the user might have moved the
   cursor toward a link or hovered it, even momentarily, or paused scrolling when the link is one of
   the more prominent ones in the viewport. The author is seeking to capture as many navigations as
   possible, as early as possible.<dt>"<dfn id=sr-eagerness-moderate><code>moderate</code></dfn>"<dd><p>User agents should enact the candidate if user behavior suggests the user may navigate to
   this URL in the near future. For instance, the user might have scrolled a link into the viewport
   and shown signs of being likely to click it, e.g., by moving the cursor over it for some time.
   The developer is seeking a balance between "<code id=speculation-rules-data-model:sr-eagerness-eager><a href=#sr-eagerness-eager>eager</a></code>" and
   "<code id=speculation-rules-data-model:sr-eagerness-conservative><a href=#sr-eagerness-conservative>conservative</a></code>".<dt>"<dfn id=sr-eagerness-conservative><code>conservative</code></dfn>"<dd><p>User agents should enact the candidate only when the user is very likely to navigate to
   this URL at any moment. For instance, the user might have begun to interact with a link. The
   developer is seeking to capture some of the benefits of speculative loading with a fairly small
   tradeoff of resources.</dl>

  <p>A <a href=#speculation-rule-eagerness id=speculation-rules-data-model:speculation-rule-eagerness-2>speculation rule eagerness</a> <var>A</var> is <dfn id=sr-eagerness-less-eager>less eager</dfn> than another <a href=#speculation-rule-eagerness id=speculation-rules-data-model:speculation-rule-eagerness-3>speculation rule
  eagerness</a> <var>B</var> if <var>A</var> follows <var>B</var> in the above list.</p>

  <p>A <a href=#speculation-rule-eagerness id=speculation-rules-data-model:speculation-rule-eagerness-4>speculation rule eagerness</a> <var>A</var> is <dfn id=sr-eagerness-at-least-as-eager>at least as eager</dfn> as another <a href=#speculation-rule-eagerness id=speculation-rules-data-model:speculation-rule-eagerness-5>speculation rule
  eagerness</a> <var>B</var> if <var>A</var> is not <a href=#sr-eagerness-less-eager id=speculation-rules-data-model:sr-eagerness-less-eager>less
  eager</a> than <var>B</var>.</p>

  <hr>

  <p>A <dfn id=speculation-rule-tag>speculation rule tag</dfn> is either an <a id=speculation-rules-data-model:ascii-string href=https://infra.spec.whatwg.org/#ascii-string data-x-internal=ascii-string>ASCII string</a> whose <a href=https://infra.spec.whatwg.org/#code-point id=speculation-rules-data-model:code-point data-x-internal=code-point>code points</a> are all in the range U+0020 to U+007E inclusive, or
  null.</p>

  <p class=note>This code point range restriction ensures the value can be sent in an HTTP header
  with no escaping or modification.</p>

  <hr>

  <p>A <dfn id=speculation-rule-requirement>speculation rule requirement</dfn> is the string "<code>anonymous-client-ip-when-cross-origin</code>".</p>

  <p class=note>In the future, more possible requirements might be defined.</p>

  <h5 id=speculation-rules-parsing><span class=secno>7.6.1.2</span> Parsing<a href=#speculation-rules-parsing class=self-link></a></h5>

  <div class=note>
   <p>Since speculative loading is a progressive enhancement, this standard is fairly conservative
   in its parsing behavior. In particular, unknown keys or invalid values usually cause parsing
   failure, since it is safer to do nothing than to possibly misinterpret a speculation rule.</p>

   <p>That said, parsing failure for a single speculation rule still allows other speculation rules
   to be processed. It is only in the case of top-level misconfiguration that the entire speculation
   rule set is discarded.</p>
  </div>

  <p>To <dfn id=parse-a-speculation-rule-set-string>parse a speculation rule set string</dfn> given a <a id=speculation-rules-parsing:string href=https://infra.spec.whatwg.org/#string data-x-internal=string>string</a> <var>input</var>,
  a <code id=speculation-rules-parsing:document><a href=dom.html#document>Document</a></code> <var>document</var>, and a <a id=speculation-rules-parsing:url href=https://url.spec.whatwg.org/#concept-url data-x-internal=url>URL</a> <var>baseURL:</var></p>

  <ol><li><p>Let <var>parsed</var> be the result of <a href=https://infra.spec.whatwg.org/#parse-a-json-string-to-an-infra-value id=speculation-rules-parsing:parse-a-json-string-to-an-infra-value data-x-internal=parse-a-json-string-to-an-infra-value>parsing a JSON string to an Infra value</a> given <var>input</var>.<li><p>If <var>parsed</var> is not a <a href=https://infra.spec.whatwg.org/#ordered-map id=speculation-rules-parsing:ordered-map data-x-internal=ordered-map>map</a>, then throw a
   <code id=speculation-rules-parsing:typeerror><a data-x-internal=typeerror href=https://tc39.es/ecma262/#sec-native-error-types-used-in-this-standard-typeerror>TypeError</a></code> indicating that the top-level value needs to be a JSON object.</p>

   <li><p>Let <var>result</var> be a new <a href=#speculation-rule-set id=speculation-rules-parsing:speculation-rule-set>speculation rule set</a>.<li><p>Let <var>tag</var> be null.<li>
    <p>If <var>parsed</var>["<code>tag</code>"] <a href=https://infra.spec.whatwg.org/#map-exists id=speculation-rules-parsing:map-exists data-x-internal=map-exists>exists</a>:</p>

    <ol><li><p>If <var>parsed</var>["<code>tag</code>"] is not a <a href=#speculation-rule-tag id=speculation-rules-parsing:speculation-rule-tag>speculation rule
     tag</a>, then throw a <code id=speculation-rules-parsing:typeerror-2><a data-x-internal=typeerror href=https://tc39.es/ecma262/#sec-native-error-types-used-in-this-standard-typeerror>TypeError</a></code> indicating that the speculation rule tag is
     invalid.</p>

     <li><p>Set <var>tag</var> to <var>parsed</var>["<code>tag</code>"].</ol>
   <li><p>Let <var>typesToTreatAsPrefetch</var> be « "<code>prefetch</code>" ».<li>
    <p>The user agent may <a href=https://infra.spec.whatwg.org/#list-append id=speculation-rules-parsing:list-append data-x-internal=list-append>append</a> "<code>prerender</code>" to <var>typesToTreatAsPrefetch</var>.</p>

    <p id=note-speculation-rules-parse-prerender-as-prefetch class=note><a href=#note-speculation-rules-parse-prerender-as-prefetch class=self-link></a>Since this specification
    only includes prefetching, this allows user agents to treat requests for prerendering as
    requests for prefetching. User agents which implement prerendering, per the <cite>Prerendering
    Revamped</cite> specification, will instead interpret these as prerender requests.
    <a href=references.html#refsPRERENDERING-REVAMPED>[PRERENDERING-REVAMPED]</a></p>
   <li>
    <p><a href=https://infra.spec.whatwg.org/#list-iterate id=speculation-rules-parsing:list-iterate data-x-internal=list-iterate>For each</a> <var>type</var> of
    <var>typesToTreatAsPrefetch</var>:</p>

    <ol><li>
      <p>If <var>parsed</var>[<var>type</var>] <a href=https://infra.spec.whatwg.org/#map-exists id=speculation-rules-parsing:map-exists-2 data-x-internal=map-exists>exists</a>:</p>

      <ol><li>
        <p>If <var>parsed</var>[<var>type</var>] is a <a id=speculation-rules-parsing:list href=https://infra.spec.whatwg.org/#list data-x-internal=list>list</a>, then <a href=https://infra.spec.whatwg.org/#list-iterate id=speculation-rules-parsing:list-iterate-2 data-x-internal=list-iterate>for each</a> <var>rule</var> of <var>parsed</var>[<var>type</var>]:</p>

        <ol><li><p>Let <var>rule</var> be the result of <a href=#parse-a-speculation-rule id=speculation-rules-parsing:parse-a-speculation-rule>parsing
         a speculation rule</a> given <var>rule</var>, <var>tag</var>, <var>document</var>, and
         <var>baseURL</var>.<li><p>If <var>rule</var> is null, then <a id=speculation-rules-parsing:continue href=https://infra.spec.whatwg.org/#iteration-continue data-x-internal=continue>continue</a>.<li><p><a href=https://infra.spec.whatwg.org/#list-append id=speculation-rules-parsing:list-append-2 data-x-internal=list-append>Append</a> <var>rule</var> to <var>result</var>'s
         <a href=#sr-set-prefetch id=speculation-rules-parsing:sr-set-prefetch>prefetch rules</a>.</ol>
       <li><p>Otherwise, the user agent may <a id=speculation-rules-parsing:report-a-warning-to-the-console href=https://console.spec.whatwg.org/#report-a-warning-to-the-console data-x-internal=report-a-warning-to-the-console>report a warning to the console</a> indicating
       that the rules list for <var>type</var> needs to be a JSON array.</ol>
     </ol>
   <li><p>Return <var>result</var>.</ol>

  <p>To <dfn id=parse-a-speculation-rule>parse a speculation rule</dfn> given a <a href=https://infra.spec.whatwg.org/#ordered-map id=speculation-rules-parsing:ordered-map-2 data-x-internal=ordered-map>map</a>
  <var>input</var>, a <a href=#speculation-rule-tag id=speculation-rules-parsing:speculation-rule-tag-2>speculation rule tag</a> <var>rulesetLevelTag</var>, a
  <code id=speculation-rules-parsing:document-2><a href=dom.html#document>Document</a></code> <var>document</var>, and a <a id=speculation-rules-parsing:url-2 href=https://url.spec.whatwg.org/#concept-url data-x-internal=url>URL</a> <var>baseURL</var>:</p>

  <ol><li>
    <p>If <var>input</var> is not a <a href=https://infra.spec.whatwg.org/#ordered-map id=speculation-rules-parsing:ordered-map-3 data-x-internal=ordered-map>map</a>:</p>

    <ol><li><p>The user agent may <a id=speculation-rules-parsing:report-a-warning-to-the-console-2 href=https://console.spec.whatwg.org/#report-a-warning-to-the-console data-x-internal=report-a-warning-to-the-console>report a warning to the console</a> indicating that the rule
     needs to be a JSON object.<li><p>Return null.</ol>
   <li>
    <p>If <var>input</var> has any <a href=https://infra.spec.whatwg.org/#map-key id=speculation-rules-parsing:map-key data-x-internal=map-key>key</a> other than "<code>source</code>", "<code>urls</code>", "<code>where</code>", "<code>relative_to</code>", "<code>eagerness</code>",  "<code>referrer_policy</code>", "<code>tag</code>", "<code>requires</code>", "<code>expects_no_vary_search</code>", or "<code>target_hint</code>":</p>

    <ol><li><p>The user agent may <a id=speculation-rules-parsing:report-a-warning-to-the-console-3 href=https://console.spec.whatwg.org/#report-a-warning-to-the-console data-x-internal=report-a-warning-to-the-console>report a warning to the console</a> indicating that the rule
     has unrecognized keys.<li><p>Return null.</ol>

    <p id=note-speculation-rules-parse-target-hint class=note><a href=#note-speculation-rules-parse-target-hint class=self-link></a>"<code>target_hint</code>" has no impact on the processing model in this standard. However,
    implementations of <cite>Prerendering Revamped</cite> can use it for prerendering rules, and so
    requiring user agents to fail parsing such rules would be counterproductive.
    <a href=references.html#refsPRERENDERING-REVAMPED>[PRERENDERING-REVAMPED]</a>.</p>
   <li><p>Let <var>source</var> be null.<li><p>If <var>input</var>["<code>source</code>"] <a href=https://infra.spec.whatwg.org/#map-exists id=speculation-rules-parsing:map-exists-3 data-x-internal=map-exists>exists</a>, then set <var>source</var> to <var>input</var>["<code>source</code>"].<li><p>Otherwise, if <var>input</var>["<code>urls</code>"] <a href=https://infra.spec.whatwg.org/#map-exists id=speculation-rules-parsing:map-exists-4 data-x-internal=map-exists>exists</a> and <var>input</var>["<code>where</code>"] does not <a href=https://infra.spec.whatwg.org/#map-exists id=speculation-rules-parsing:map-exists-5 data-x-internal=map-exists>exist</a>, then set <var>source</var> to "<code>list</code>".<li><p>Otherwise, if <var>input</var>["<code>where</code>"] <a href=https://infra.spec.whatwg.org/#map-exists id=speculation-rules-parsing:map-exists-6 data-x-internal=map-exists>exists</a> and <var>input</var>["<code>urls</code>"] does not <a href=https://infra.spec.whatwg.org/#map-exists id=speculation-rules-parsing:map-exists-7 data-x-internal=map-exists>exist</a>, then set <var>source</var> to "<code>document</code>".<li>
    <p>If <var>source</var> is neither "<code>list</code>" nor "<code>document</code>":</p>

    <ol><li><p>The user agent may <a id=speculation-rules-parsing:report-a-warning-to-the-console-4 href=https://console.spec.whatwg.org/#report-a-warning-to-the-console data-x-internal=report-a-warning-to-the-console>report a warning to the console</a> indicating that a source
     could not be inferred or an invalid source was specified.<li><p>Return null.</ol>
   <li><p>Let <var>urls</var> be an empty <a id=speculation-rules-parsing:list-2 href=https://infra.spec.whatwg.org/#list data-x-internal=list>list</a>.<li><p>Let <var>predicate</var> be null.<li>
    <p>If <var>source</var> is "<code>list</code>":</p>

    <ol><li>
      <p>If <var>input</var>["<code>where</code>"] <a href=https://infra.spec.whatwg.org/#map-exists id=speculation-rules-parsing:map-exists-8 data-x-internal=map-exists>exists</a>:</p>

      <ol><li><p>The user agent may <a id=speculation-rules-parsing:report-a-warning-to-the-console-5 href=https://console.spec.whatwg.org/#report-a-warning-to-the-console data-x-internal=report-a-warning-to-the-console>report a warning to the console</a> indicating that there
       were conflicting sources for this rule.<li><p>Return null.</ol>
     <li>
      <p>If <var>input</var>["<code>relative_to</code>"] <a href=https://infra.spec.whatwg.org/#map-exists id=speculation-rules-parsing:map-exists-9 data-x-internal=map-exists>exists</a>:</p>

      <ol><li>
        <p>If <var>input</var>["<code>relative_to</code>"] is neither "<code>ruleset</code>" nor "<code>document</code>":</p>

        <ol><li><p>The user agent may <a id=speculation-rules-parsing:report-a-warning-to-the-console-6 href=https://console.spec.whatwg.org/#report-a-warning-to-the-console data-x-internal=report-a-warning-to-the-console>report a warning to the console</a> indicating that the
         supplied relative-to value was invalid.<li><p>Return null.</ol>
       <li><p>If <var>input</var>["<code>relative_to</code>"] is "<code>document</code>", then set <var>baseURL</var> to <var>document</var>'s
       <a id=speculation-rules-parsing:document-base-url href=urls-and-fetching.html#document-base-url>document base URL</a>.</ol>
     <li>
      <p>If <var>input</var>["<code>urls</code>"] does not <a href=https://infra.spec.whatwg.org/#map-exists id=speculation-rules-parsing:map-exists-10 data-x-internal=map-exists>exist</a> or is not a <a id=speculation-rules-parsing:list-3 href=https://infra.spec.whatwg.org/#list data-x-internal=list>list</a>:</p>

      <ol><li><p>The user agent may <a id=speculation-rules-parsing:report-a-warning-to-the-console-7 href=https://console.spec.whatwg.org/#report-a-warning-to-the-console data-x-internal=report-a-warning-to-the-console>report a warning to the console</a> indicating that the
       supplied URL list was invalid.<li><p>Return null.</ol>
     <li>
      <p><a href=https://infra.spec.whatwg.org/#list-iterate id=speculation-rules-parsing:list-iterate-3 data-x-internal=list-iterate>For each</a> <var>urlString</var> of <var>input</var>["<code>urls</code>"]:</p>

      <ol><li>
        <p>If <var>urlString</var> is not a string:</p>

        <ol><li><p>The user agent may <a id=speculation-rules-parsing:report-a-warning-to-the-console-8 href=https://console.spec.whatwg.org/#report-a-warning-to-the-console data-x-internal=report-a-warning-to-the-console>report a warning to the console</a> indicating that the
         supplied URL must be a string.<li><p>Return null.</ol>
       <li><p>Let <var>parsedURL</var> be the result of <a href=https://url.spec.whatwg.org/#concept-url-parser id=speculation-rules-parsing:url-parser data-x-internal=url-parser>URL parsing</a>
       <var>urlString</var> with <var>baseURL</var>.<li>
        <p>If <var>parsedURL</var> is failure, or <var>parsedURL</var>'s <a href=https://url.spec.whatwg.org/#concept-url-scheme id=speculation-rules-parsing:concept-url-scheme data-x-internal=concept-url-scheme>scheme</a> is not an <a id=speculation-rules-parsing:http(s)-scheme href=https://fetch.spec.whatwg.org/#http-scheme data-x-internal=http(s)-scheme>HTTP(S) scheme</a>:</p>

        <ol><li><p>The user agent may <a id=speculation-rules-parsing:report-a-warning-to-the-console-9 href=https://console.spec.whatwg.org/#report-a-warning-to-the-console data-x-internal=report-a-warning-to-the-console>report a warning to the console</a> indicating that the
         supplied URL string was unparseable.<li><p><a id=speculation-rules-parsing:continue-2 href=https://infra.spec.whatwg.org/#iteration-continue data-x-internal=continue>Continue</a>.</ol>
       <li><p><a href=https://infra.spec.whatwg.org/#list-append id=speculation-rules-parsing:list-append-3 data-x-internal=list-append>Append</a> <var>parsedURL</var> to
       <var>urls</var>.</ol>
     </ol>
   <li>
    <p>If <var>source</var> is "<code>document</code>":</p>

    <ol><li>
      <p>If <var>input</var>["<code>urls</code>"] or <var>input</var>["<code>relative_to</code>"] <a href=https://infra.spec.whatwg.org/#map-exists id=speculation-rules-parsing:map-exists-11 data-x-internal=map-exists>exists</a>:</p>

      <ol><li><p>The user agent may <a id=speculation-rules-parsing:report-a-warning-to-the-console-10 href=https://console.spec.whatwg.org/#report-a-warning-to-the-console data-x-internal=report-a-warning-to-the-console>report a warning to the console</a> indicating that there
       were conflicting sources for this rule.<li><p>Return null.</ol>
     <li>
      <p>If <var>input</var>["<code>where</code>"] does not <a href=https://infra.spec.whatwg.org/#map-exists id=speculation-rules-parsing:map-exists-12 data-x-internal=map-exists>exist</a>, then set <var>predicate</var> to a <a href=#document-rule-conjunction id=speculation-rules-parsing:document-rule-conjunction>document rule
      conjunction</a> whose <a href=#sr-dr-c-clauses id=speculation-rules-parsing:sr-dr-c-clauses>clauses</a> is an empty
      <a id=speculation-rules-parsing:list-4 href=https://infra.spec.whatwg.org/#list data-x-internal=list>list</a>.</p>

      <p class=note>Such a predicate will match all links.</p>
     <li><p>Otherwise, set <var>predicate</var> to the result of <a href=#parse-a-document-rule-predicate id=speculation-rules-parsing:parse-a-document-rule-predicate>parsing a document rule predicate</a> given <var>input</var>["<code>where</code>"], <var>document</var>, and <var>baseURL</var>.<li><p>If <var>predicate</var> is null, then return null.</ol>
   <li><p>Let <var>eagerness</var> be "<code id=speculation-rules-parsing:sr-eagerness-immediate><a href=#sr-eagerness-immediate>immediate</a></code>" if
   <var>source</var> is "<code>list</code>"; otherwise, "<code id=speculation-rules-parsing:sr-eagerness-conservative><a href=#sr-eagerness-conservative>conservative</a></code>".<li>
    <p>If <var>input</var>["<code>eagerness</code>"] <a href=https://infra.spec.whatwg.org/#map-exists id=speculation-rules-parsing:map-exists-13 data-x-internal=map-exists>exists</a>:</p>

    <ol><li>
      <p>If <var>input</var>["<code>eagerness</code>"] is not a <a href=#speculation-rule-eagerness id=speculation-rules-parsing:speculation-rule-eagerness>speculation rule
      eagerness</a>:</p>

      <ol><li><p>The user agent may <a id=speculation-rules-parsing:report-a-warning-to-the-console-11 href=https://console.spec.whatwg.org/#report-a-warning-to-the-console data-x-internal=report-a-warning-to-the-console>report a warning to the console</a> indicating that the
       eagerness was invalid.<li><p>Return null.</ol>
     <li><p>Set <var>eagerness</var> to <var>input</var>["<code>eagerness</code>"].</ol>
   <li><p>Let <var>referrerPolicy</var> be the empty string.<li>
    <p>If <var>input</var>["<code>referrer_policy</code>"] <a href=https://infra.spec.whatwg.org/#map-exists id=speculation-rules-parsing:map-exists-14 data-x-internal=map-exists>exists</a>:</p>

    <ol><li>
      <p>If <var>input</var>["<code>referrer_policy</code>"] is not a <a id=speculation-rules-parsing:referrer-policy href=https://w3c.github.io/webappsec-referrer-policy/#referrer-policy data-x-internal=referrer-policy>referrer
      policy</a>:</p>

      <ol><li><p>The user agent may <a id=speculation-rules-parsing:report-a-warning-to-the-console-12 href=https://console.spec.whatwg.org/#report-a-warning-to-the-console data-x-internal=report-a-warning-to-the-console>report a warning to the console</a> indicating that the
       referrer policy was invalid.<li><p>Return null.</ol>
     <li><p>Set <var>referrerPolicy</var> to <var>input</var>["<code>referrer_policy</code>"].</ol>
   <li><p>Let <var>tags</var> be an empty <a href=https://infra.spec.whatwg.org/#ordered-set id=speculation-rules-parsing:set data-x-internal=set>ordered set</a>.<li><p>If <var>rulesetLevelTag</var> is not null, then <a href=https://infra.spec.whatwg.org/#set-append id=speculation-rules-parsing:set-append data-x-internal=set-append>append</a>
   <var>rulesetLevelTag</var> to <var>tags</var>.<li>
    <p>If <var>input</var>["<code>tag</code>"] <a href=https://infra.spec.whatwg.org/#map-exists id=speculation-rules-parsing:map-exists-15 data-x-internal=map-exists>exists</a>:</p>

    <ol><li>
      <p>If <var>input</var>["<code>tag</code>"] is not a <a href=#speculation-rule-tag id=speculation-rules-parsing:speculation-rule-tag-3>speculation rule
      tag</a>:</p>

      <ol><li><p>The user agent may <a id=speculation-rules-parsing:report-a-warning-to-the-console-13 href=https://console.spec.whatwg.org/#report-a-warning-to-the-console data-x-internal=report-a-warning-to-the-console>report a warning to the console</a> indicating that the
       tag was invalid.<li><p>Return null.</ol>
     <li><p><a href=https://infra.spec.whatwg.org/#set-append id=speculation-rules-parsing:set-append-2 data-x-internal=set-append>Append</a> <var>input</var>["<code>tag</code>"]
     to <var>tags</var>.</ol>
   <li><p>If <var>tags</var> <a href=https://infra.spec.whatwg.org/#list-is-empty id=speculation-rules-parsing:list-is-empty data-x-internal=list-is-empty>is empty</a>, then <a href=https://infra.spec.whatwg.org/#set-append id=speculation-rules-parsing:set-append-3 data-x-internal=set-append>append</a> null to <var>tags</var>.<li><p><a id=speculation-rules-parsing:assert href=https://infra.spec.whatwg.org/#assert data-x-internal=assert>Assert</a>: <var>tags</var>'s <a href=https://infra.spec.whatwg.org/#list-size id=speculation-rules-parsing:list-size data-x-internal=list-size>size</a> is either 1 or
   2.<li><p>Let <var>requirements</var> be an empty <a href=https://infra.spec.whatwg.org/#ordered-set id=speculation-rules-parsing:set-2 data-x-internal=set>ordered set</a>.<li>
    <p>If <var>input</var>["<code>requires</code>"] <a href=https://infra.spec.whatwg.org/#map-exists id=speculation-rules-parsing:map-exists-16 data-x-internal=map-exists>exists</a>:</p>

    <ol><li>
      <p>If <var>input</var>["<code>requires</code>"] is not a <a id=speculation-rules-parsing:list-5 href=https://infra.spec.whatwg.org/#list data-x-internal=list>list</a>:</p>

      <ol><li><p>The user agent may <a id=speculation-rules-parsing:report-a-warning-to-the-console-14 href=https://console.spec.whatwg.org/#report-a-warning-to-the-console data-x-internal=report-a-warning-to-the-console>report a warning to the console</a> indicating that the
       requirements were not understood.<li><p>Return null.</ol>
     <li>
      <p><a href=https://infra.spec.whatwg.org/#list-iterate id=speculation-rules-parsing:list-iterate-4 data-x-internal=list-iterate>For each</a> <var>requirement</var> of
      <var>input</var>["<code>requires</code>"]:</p>

      <ol><li>
        <p>If <var>requirement</var> is not a <a href=#speculation-rule-requirement id=speculation-rules-parsing:speculation-rule-requirement>speculation rule requirement</a>:</p>

        <ol><li><p>The user agent may <a id=speculation-rules-parsing:report-a-warning-to-the-console-15 href=https://console.spec.whatwg.org/#report-a-warning-to-the-console data-x-internal=report-a-warning-to-the-console>report a warning to the console</a> indicating that the
         requirement was not understood.<li><p>Return null.</ol>
       <li><p><a href=https://infra.spec.whatwg.org/#set-append id=speculation-rules-parsing:set-append-4 data-x-internal=set-append>Append</a> <var>requirement</var> to
       <var>requirements</var>.</ol>
     </ol>
   <li><p>Let <var>noVarySearchHint</var> be the <a id=speculation-rules-parsing:default-url-search-variance href=https://httpwg.org/http-extensions/draft-ietf-httpbis-no-vary-search.html#name-data-model data-x-internal=default-url-search-variance>default URL search variance</a>.<li>
    <p>If <var>input</var>["<code>expects_no_vary_search</code>"] <a href=https://infra.spec.whatwg.org/#map-exists id=speculation-rules-parsing:map-exists-17 data-x-internal=map-exists>exists</a>:</p>

    <ol><li>
      <p>If <var>input</var>["<code>expects_no_vary_search</code>"] is not a
      <a id=speculation-rules-parsing:string-2 href=https://infra.spec.whatwg.org/#string data-x-internal=string>string</a>:</p>

      <ol><li><p>The user agent may <a id=speculation-rules-parsing:report-a-warning-to-the-console-16 href=https://console.spec.whatwg.org/#report-a-warning-to-the-console data-x-internal=report-a-warning-to-the-console>report a warning to the console</a> indicating that the
       `<code id=speculation-rules-parsing:no-vary-search><a data-x-internal=no-vary-search href=https://httpwg.org/http-extensions/draft-ietf-httpbis-no-vary-search.html#name-http-header-field-definitio>No-Vary-Search</a></code>` hint was invalid.<li><p>Return null.</ol>
     <li><p>Set <var>noVarySearchHint</var> to the result of <a href=https://httpwg.org/http-extensions/draft-ietf-httpbis-no-vary-search.html#parse-a-url-search-variance id=speculation-rules-parsing:parse-a-url-search-variance data-x-internal=parse-a-url-search-variance>parsing a URL search variance</a> given <var>input</var>["<code>expects_no_vary_search</code>"].</ol>
   <li>
    <p>Return a <a href=#speculation-rule id=speculation-rules-parsing:speculation-rule>speculation rule</a> with:</p>

    <dl class=props><dt><a href=#sr-urls id=speculation-rules-parsing:sr-urls>URLs</a><dd><var>urls</var><dt><a href=#sr-predicate id=speculation-rules-parsing:sr-predicate>predicate</a><dd><var>predicate</var><dt><a href=#sr-eagerness id=speculation-rules-parsing:sr-eagerness>eagerness</a><dd><var>eagerness</var><dt><a href=#sr-referrer-policy id=speculation-rules-parsing:sr-referrer-policy>referrer policy</a><dd><var>referrerPolicy</var><dt><a href=#sr-tags id=speculation-rules-parsing:sr-tags>tags</a><dd><var>tags</var><dt><a href=#sr-requirements id=speculation-rules-parsing:sr-requirements>requirements</a><dd><var>requirements</var><dt><a href=#sr-nvs-hint id=speculation-rules-parsing:sr-nvs-hint>No-Vary-Search hint</a><dd><var>noVarySearchHint</var></dl>
   </ol>

  <p>To <dfn id=parse-a-document-rule-predicate>parse a document rule predicate</dfn> given a value <var>input</var>, a
  <code id=speculation-rules-parsing:document-3><a href=dom.html#document>Document</a></code> <var>document</var>, and a <a id=speculation-rules-parsing:url-3 href=https://url.spec.whatwg.org/#concept-url data-x-internal=url>URL</a> <var>baseURL</var>:</p>

  <ol><li>
    <p>If <var>input</var> is not a <a href=https://infra.spec.whatwg.org/#ordered-map id=speculation-rules-parsing:ordered-map-4 data-x-internal=ordered-map>map</a>:</p>

    <ol><li><p>The user agent may <a id=speculation-rules-parsing:report-a-warning-to-the-console-17 href=https://console.spec.whatwg.org/#report-a-warning-to-the-console data-x-internal=report-a-warning-to-the-console>report a warning to the console</a> indicating that the
     document rule predicate was invalid.<li><p>Return null.</ol>
   <li>
    <p>If <var>input</var> does not <a href=https://infra.spec.whatwg.org/#map-exists id=speculation-rules-parsing:map-exists-18 data-x-internal=map-exists>contain</a> exactly one of "<code>and</code>", "<code>or</code>", "<code>not</code>", "<code>href_matches</code>", or "<code>selector_matches</code>":</p>

    <ol><li><p>The user agent may <a id=speculation-rules-parsing:report-a-warning-to-the-console-18 href=https://console.spec.whatwg.org/#report-a-warning-to-the-console data-x-internal=report-a-warning-to-the-console>report a warning to the console</a> indicating that the
     document rule predicate was empty or ambiguous.<li><p>Return null.</ol>
   <li><p>Let <var>predicateType</var> be the single key found in the previous step.<li>
    <p>If <var>predicateType</var> is "<code>and</code>" or "<code>or</code>":</p>

    <ol><li>
      <p>If <var>input</var> has any <a href=https://infra.spec.whatwg.org/#map-key id=speculation-rules-parsing:map-key-2 data-x-internal=map-key>key</a> other than
      <var>predicateType</var>:</p>

      <ol><li><p>The user agent may <a id=speculation-rules-parsing:report-a-warning-to-the-console-19 href=https://console.spec.whatwg.org/#report-a-warning-to-the-console data-x-internal=report-a-warning-to-the-console>report a warning to the console</a> indicating that the
       document rule predicate had unexpected extra options.<li><p>Return null.</ol>
     <li>
      <p>If <var>input</var>[<var>predicateType</var>] is not a <a id=speculation-rules-parsing:list-6 href=https://infra.spec.whatwg.org/#list data-x-internal=list>list</a>:</p>

      <ol><li><p>The user agent may <a id=speculation-rules-parsing:report-a-warning-to-the-console-20 href=https://console.spec.whatwg.org/#report-a-warning-to-the-console data-x-internal=report-a-warning-to-the-console>report a warning to the console</a> indicating that the
       document rule predicate had an invalid clause list.<li><p>Return null.</ol>
     <li><p>Let <var>clauses</var> be an empty <a id=speculation-rules-parsing:list-7 href=https://infra.spec.whatwg.org/#list data-x-internal=list>list</a>.<li>
      <p><a href=https://infra.spec.whatwg.org/#list-iterate id=speculation-rules-parsing:list-iterate-5 data-x-internal=list-iterate>For each</a> <var>rawClause</var> of
      <var>input</var>[<var>predicateType</var>]:</p>

      <ol><li><p>Let <var>clause</var> be the result of <a href=#parse-a-document-rule-predicate id=speculation-rules-parsing:parse-a-document-rule-predicate-2>parsing a document rule predicate</a> given <var>rawClause</var>,
       <var>document</var>, and <var>baseURL</var>.<li><p>If <var>clause</var> is null, then return null.<li><p><a href=https://infra.spec.whatwg.org/#list-append id=speculation-rules-parsing:list-append-4 data-x-internal=list-append>Append</a> <var>clause</var> to
       <var>clauses</var>.</ol>
     <li><p>If <var>predicateType</var> is "<code>and</code>", then return a
     <a href=#document-rule-conjunction id=speculation-rules-parsing:document-rule-conjunction-2>document rule conjunction</a> whose <a href=#sr-dr-c-clauses id=speculation-rules-parsing:sr-dr-c-clauses-2>clauses</a> is
     <var>clauses</var>.<li><p>Return a <a href=#document-rule-disjunction id=speculation-rules-parsing:document-rule-disjunction>document rule disjunction</a> whose <a href=#sr-dr-d-clauses id=speculation-rules-parsing:sr-dr-d-clauses>clauses</a> is <var>clauses</var>.</ol>
   <li>
    <p>If <var>predicateType</var> is "<code>not</code>":</p>

    <ol><li>
      <p>If <var>input</var> has any <a href=https://infra.spec.whatwg.org/#map-key id=speculation-rules-parsing:map-key-3 data-x-internal=map-key>key</a> other than "<code>not</code>":</p>

      <ol><li><p>The user agent may <a id=speculation-rules-parsing:report-a-warning-to-the-console-21 href=https://console.spec.whatwg.org/#report-a-warning-to-the-console data-x-internal=report-a-warning-to-the-console>report a warning to the console</a> indicating that the
       document rule predicate had unexpected extra options.<li><p>Return null.</ol>
     <li><p>Let <var>clause</var> be the result of <a href=#parse-a-document-rule-predicate id=speculation-rules-parsing:parse-a-document-rule-predicate-3>parsing a document rule predicate</a> given
     <var>input</var>[<var>predicateType</var>], <var>document</var>, and
     <var>baseURL</var>.<li><p>If <var>clause</var> is null, then return null.<li><p>Return a <a href=#document-rule-negation id=speculation-rules-parsing:document-rule-negation>document rule negation</a> whose <a href=#sr-dr-n-clause id=speculation-rules-parsing:sr-dr-n-clause>clause</a> is <var>clause</var>.</ol>
   <li>
    <p>If <var>predicateType</var> is "<code>href_matches</code>":</p>

    <ol><li>
      <p>If <var>input</var> has any <a href=https://infra.spec.whatwg.org/#map-key id=speculation-rules-parsing:map-key-4 data-x-internal=map-key>key</a> other than "<code>href_matches</code>" or "<code>relative_to</code>":</p>

      <ol><li><p>The user agent may <a id=speculation-rules-parsing:report-a-warning-to-the-console-22 href=https://console.spec.whatwg.org/#report-a-warning-to-the-console data-x-internal=report-a-warning-to-the-console>report a warning to the console</a> indicating that the
       document rule predicate had unexpected extra options.<li><p>Return null.</ol>
     <li>
      <p>If <var>input</var>["<code>relative_to</code>"] <a href=https://infra.spec.whatwg.org/#map-exists id=speculation-rules-parsing:map-exists-19 data-x-internal=map-exists>exists</a>:</p>

      <ol><li>
        <p>If <var>input</var>["<code>relative_to</code>"] is neither "<code>ruleset</code>" nor "<code>document</code>":</p>

        <ol><li><p>The user agent may <a id=speculation-rules-parsing:report-a-warning-to-the-console-23 href=https://console.spec.whatwg.org/#report-a-warning-to-the-console data-x-internal=report-a-warning-to-the-console>report a warning to the console</a> indicating that the
         supplied relative-to value was invalid.<li><p>Return null.</ol>
       <li><p>If <var>input</var>["<code>relative_to</code>"] is "<code>document</code>", then set <var>baseURL</var> to <var>document</var>'s
       <a id=speculation-rules-parsing:document-base-url-2 href=urls-and-fetching.html#document-base-url>document base URL</a>.</ol>
     <li><p>Let <var>rawPatterns</var> be <var>input</var>["<code>href_matches</code>"].<li><p>If <var>rawPatterns</var> is not a <a id=speculation-rules-parsing:list-8 href=https://infra.spec.whatwg.org/#list data-x-internal=list>list</a>, then set <var>rawPatterns</var> to
     « <var>rawPatterns</var> ».<li><p>Let <var>patterns</var> be an empty <a id=speculation-rules-parsing:list-9 href=https://infra.spec.whatwg.org/#list data-x-internal=list>list</a>.<li>
      <p><a href=https://infra.spec.whatwg.org/#list-iterate id=speculation-rules-parsing:list-iterate-6 data-x-internal=list-iterate>For each</a> <var>rawPattern</var> of
      <var>rawPatterns</var>:</p>

      <ol><li><p>Let <var>pattern</var> be the result of <a href=https://urlpattern.spec.whatwg.org/#build-a-url-pattern-from-an-infra-value id=speculation-rules-parsing:build-a-url-pattern-from-an-infra-value data-x-internal=build-a-url-pattern-from-an-infra-value>building a URL pattern from an Infra value</a> given <var>rawPattern</var>
       and <var>baseURL</var>. If this step throws and exception, catch the exception and set
       <var>pattern</var> to null.<li>
        <p>If <var>pattern</var> is null:</p>

        <ol><li><p>The user agent may <a id=speculation-rules-parsing:report-a-warning-to-the-console-24 href=https://console.spec.whatwg.org/#report-a-warning-to-the-console data-x-internal=report-a-warning-to-the-console>report a warning to the console</a> indicating that the
         supplied URL pattern was invalid.<li><p>Return null.</ol>
       <li><p><a href=https://infra.spec.whatwg.org/#list-append id=speculation-rules-parsing:list-append-5 data-x-internal=list-append>Append</a> <var>pattern</var> to
       <var>patterns</var>.</ol>
     <li><p>Return a <a href=#document-rule-url-pattern-predicate id=speculation-rules-parsing:document-rule-url-pattern-predicate>document rule URL pattern predicate</a> whose <a href=#sr-dr-urlpattern-patterns id=speculation-rules-parsing:sr-dr-urlpattern-patterns>patterns</a> is <var>patterns</var>.</ol>
   <li>
    <p>If <var>predicateType</var> is "<code>selector_matches</code>":</p>

    <ol><li>
      <p>If <var>input</var> has any <a href=https://infra.spec.whatwg.org/#map-key id=speculation-rules-parsing:map-key-5 data-x-internal=map-key>key</a> other than "<code>selector_matches</code>":</p>

      <ol><li><p>The user agent may <a id=speculation-rules-parsing:report-a-warning-to-the-console-25 href=https://console.spec.whatwg.org/#report-a-warning-to-the-console data-x-internal=report-a-warning-to-the-console>report a warning to the console</a> indicating that the
       document rule predicate had unexpected extra options.<li><p>Return null.</ol>
     <li><p>Let <var>rawSelectors</var> be <var>input</var>["<code>selector_matches</code>"].<li><p>If <var>rawSelectors</var> is not a <a id=speculation-rules-parsing:list-10 href=https://infra.spec.whatwg.org/#list data-x-internal=list>list</a>, then set <var>rawSelectors</var>
     to « <var>rawSelectors</var> ».<li><p>Let <var>selectors</var> be an empty <a id=speculation-rules-parsing:list-11 href=https://infra.spec.whatwg.org/#list data-x-internal=list>list</a>.<li>
      <p><a href=https://infra.spec.whatwg.org/#list-iterate id=speculation-rules-parsing:list-iterate-7 data-x-internal=list-iterate>For each</a> <var>rawSelector</var> of
      <var>rawSelectors</var>:</p>

      <ol><li><p>Let <var>parsedSelectorList</var> be failure.<li><p>If <var>rawSelector</var> is a string, then set <var>parsedSelectorList</var> to the
       result of <a href=https://drafts.csswg.org/selectors/#parse-a-selector id=speculation-rules-parsing:parse-a-selector data-x-internal=parse-a-selector>parsing a selector</a> given
       <var>rawSelector</var>.<li>
        <p>If <var>parsedSelectorList</var> is failure:</p>

        <ol><li><p>The user agent may <a id=speculation-rules-parsing:report-a-warning-to-the-console-26 href=https://console.spec.whatwg.org/#report-a-warning-to-the-console data-x-internal=report-a-warning-to-the-console>report a warning to the console</a> indicating that the
         supplied selector list was invalid.<li><p>Return null.</ol>
       <li><p><a href=https://infra.spec.whatwg.org/#list-iterate id=speculation-rules-parsing:list-iterate-8 data-x-internal=list-iterate>For each</a> <var>selector</var> of
       <var>parsedSelectorList</var>, <a href=https://infra.spec.whatwg.org/#list-append id=speculation-rules-parsing:list-append-6 data-x-internal=list-append>append</a> <var>selector</var>
       to <var>selectors</var>.</ol>
     <li><p>Return a <a href=#document-rule-selector-predicate id=speculation-rules-parsing:document-rule-selector-predicate>document rule selector predicate</a> whose <a href=#sr-dr-cssselector-selectors id=speculation-rules-parsing:sr-dr-cssselector-selectors>selectors</a> is <var>selectors</var>.</ol>
   <li><p><a id=speculation-rules-parsing:assert-2 href=https://infra.spec.whatwg.org/#assert data-x-internal=assert>Assert</a>: this step is never reached, as one of the previous branches was
   taken.</ol>


  <h5 id=speculation-rules-processing-model><span class=secno>7.6.1.3</span> Processing model<a href=#speculation-rules-processing-model class=self-link></a></h5>

  <p>A <dfn id=speculative-load-candidate>speculative load candidate</dfn> is a <a id=speculation-rules-processing-model:struct href=https://infra.spec.whatwg.org/#struct data-x-internal=struct>struct</a> with the following <a href=https://infra.spec.whatwg.org/#struct-item id=speculation-rules-processing-model:struct-item data-x-internal=struct-item>items</a>:</p>

  <ul><li><p><dfn id=sl-candidate-url>URL</dfn>, a <a id=speculation-rules-processing-model:url href=https://url.spec.whatwg.org/#concept-url data-x-internal=url>URL</a><li><p><dfn id=sl-candidate-nvs-hint>No-Vary-Search hint</dfn>, a <a id=speculation-rules-processing-model:url-search-variance href=https://httpwg.org/http-extensions/draft-ietf-httpbis-no-vary-search.html#name-data-model data-x-internal=url-search-variance>URL search
   variance</a><li><p><dfn id=sl-candidate-eagerness>eagerness</dfn>, a <a href=#speculation-rule-eagerness id=speculation-rules-processing-model:speculation-rule-eagerness>speculation rule
   eagerness</a><li><p><dfn id=sl-candidate-referrer-policy>referrer policy</dfn>, a <a id=speculation-rules-processing-model:referrer-policy href=https://w3c.github.io/webappsec-referrer-policy/#referrer-policy data-x-internal=referrer-policy>referrer
   policy</a><li><p><dfn id=sl-candidate-tags>tags</dfn>, an <a href=https://infra.spec.whatwg.org/#ordered-set id=speculation-rules-processing-model:set data-x-internal=set>ordered set</a> of
   <a href=#speculation-rule-tag id=speculation-rules-processing-model:speculation-rule-tag>speculation rule tags</a></ul>

  <p>A <dfn id=prefetch-candidate>prefetch candidate</dfn> is a <a href=#speculative-load-candidate id=speculation-rules-processing-model:speculative-load-candidate>speculative load candidate</a> with the following
  additional <a href=https://infra.spec.whatwg.org/#struct-item id=speculation-rules-processing-model:struct-item-2 data-x-internal=struct-item>item</a>:</p>

  <ul><li><p><dfn id=sl-candidate-anonymization-policy>anonymization policy</dfn>, a
   <a href=#prefetch-ip-anonymization-policy id=speculation-rules-processing-model:prefetch-ip-anonymization-policy>prefetch IP anonymization policy</a></ul>

  <p>A <dfn id=prefetch-ip-anonymization-policy>prefetch IP anonymization policy</dfn> is either null or a <a href=#cross-origin-prefetch-ip-anonymization-policy id=speculation-rules-processing-model:cross-origin-prefetch-ip-anonymization-policy>cross-origin prefetch
  IP anonymization policy</a>.</p>

  <p>A <dfn id=cross-origin-prefetch-ip-anonymization-policy>cross-origin prefetch IP anonymization policy</dfn> is a <a id=speculation-rules-processing-model:struct-2 href=https://infra.spec.whatwg.org/#struct data-x-internal=struct>struct</a> whose
  single <a href=https://infra.spec.whatwg.org/#struct-item id=speculation-rules-processing-model:struct-item-3 data-x-internal=struct-item>item</a> is its <dfn id=copiap-origin>origin</dfn>, an
  <a id=speculation-rules-processing-model:concept-origin href=browsers.html#concept-origin>origin</a>.</p>

  <hr>

  <p>A <a href=#speculative-load-candidate id=speculation-rules-processing-model:speculative-load-candidate-2>speculative load candidate</a> <var>candidateA</var> is <dfn id=sl-candidate-redundant-with>redundant with</dfn> another <a href=#speculative-load-candidate id=speculation-rules-processing-model:speculative-load-candidate-3>speculative load
  candidate</a> <var>candidateB</var> if the following steps return true:</p>

  <ol><li><p>If <var>candidateA</var>'s <a href=#sl-candidate-nvs-hint id=speculation-rules-processing-model:sl-candidate-nvs-hint>No-Vary-Search hint</a>
   is not equal to <var>candidateB</var>'s <a href=#sl-candidate-nvs-hint id=speculation-rules-processing-model:sl-candidate-nvs-hint-2>No-Vary-Search
   hint</a>, then return false.<li><p>If <var>candidateA</var>'s <a href=#sl-candidate-url id=speculation-rules-processing-model:sl-candidate-url>URL</a> is not
   <a id=speculation-rules-processing-model:equivalent-modulo-search-variance href=https://httpwg.org/http-extensions/draft-ietf-httpbis-no-vary-search.html#name-comparing data-x-internal=equivalent-modulo-search-variance>equivalent modulo search variance</a> to <var>candidateB</var>'s <a href=#sl-candidate-url id=speculation-rules-processing-model:sl-candidate-url-2>URL</a> given <var>candidateA</var>'s <a href=#sl-candidate-nvs-hint id=speculation-rules-processing-model:sl-candidate-nvs-hint-3>No-Vary-Search hint</a>, then return false.<li><p>Return true.</ol>

  <div id=note-sl-candidate-redundant-with-nvs-strictness class=note><a href=#note-sl-candidate-redundant-with-nvs-strictness class=self-link></a>
   <p>The requirement that the <a href=#sl-candidate-nvs-hint id=speculation-rules-processing-model:sl-candidate-nvs-hint-4>No-Vary-Search hints</a> be
   equivalent is somewhat strict. It means that some cases which could theoretically be treated as
   matching, are not treated as such. Thus, redundant speculative loads could happen.</p>

   <p>However, allowing more lenient matching makes the check no longer an equivalence relation, and
   producing such matches would require an implementation strategy that does a full comparison,
   instead of a simpler one using normalized URL keys. This is in line with the best practices for
   server operators, and attendant HTTP cache implementation notes, in <a href=https://httpwg.org/http-extensions/draft-ietf-httpbis-no-vary-search.html#section-6><cite>No
   Vary Search</cite> § 6 Comparing</a>.</p>

   <p>In practice, we do not expect this to cause redundant speculative loads, since server
   operators and the corresponding speculation rules-writing web developers will follow best
   practices and use static `<code id=speculation-rules-processing-model:no-vary-search><a data-x-internal=no-vary-search href=https://httpwg.org/http-extensions/draft-ietf-httpbis-no-vary-search.html#name-http-header-field-definitio>No-Vary-Search</a></code>` header values/speculation rule hints.</p>
  </div>

  <div id=example-sl-candidate-reundant-with-nvs-strictness class=example><a href=#example-sl-candidate-reundant-with-nvs-strictness class=self-link></a>
   <p>Consider three <a href=#speculative-load-candidate id=speculation-rules-processing-model:speculative-load-candidate-4>speculative load
   candidates</a>:</p>

   <ol><li><p><var>A</var> has a <a href=#sl-candidate-url id=speculation-rules-processing-model:sl-candidate-url-3>URL</a> of <code>https://example.com?a=1&amp;b=1</code> and a <a href=#sl-candidate-nvs-hint id=speculation-rules-processing-model:sl-candidate-nvs-hint-5>No-Vary-Search hint</a> parsed from <code>params=("a")</code>.<li><p><var>B</var> has a <a href=#sl-candidate-url id=speculation-rules-processing-model:sl-candidate-url-4>URL</a> of <code>https://example.com?a=2&amp;b=1</code> and a <a href=#sl-candidate-nvs-hint id=speculation-rules-processing-model:sl-candidate-nvs-hint-6>No-Vary-Search hint</a> parsed from <code>params=("b")</code>.<li><p><var>C</var> has a <a href=#sl-candidate-url id=speculation-rules-processing-model:sl-candidate-url-5>URL</a> of <code>https://example.com?a=2&amp;b=2</code> and a <a href=#sl-candidate-nvs-hint id=speculation-rules-processing-model:sl-candidate-nvs-hint-7>No-Vary-Search hint</a> parsed from <code>params=("a")</code>.</ol>

   <p>With the current definition of <a href=#sl-candidate-redundant-with id=speculation-rules-processing-model:sl-candidate-redundant-with>redundant
   with</a>, none of these candidates are redundant with each other. A <a href=#speculation-rule-set id=speculation-rules-processing-model:speculation-rule-set>speculation rule
   set</a> which contained all three could cause three separate speculative loads.</p>

   <p>A definition which did not require equivalent <a href=#sl-candidate-nvs-hint id=speculation-rules-processing-model:sl-candidate-nvs-hint-8>No-Vary-Search hints</a> could consider <var>A</var> and
   <var>B</var> to match (using <var>A</var>'s <a href=#sl-candidate-nvs-hint id=speculation-rules-processing-model:sl-candidate-nvs-hint-9>No-Vary-Search
   hint</a>), and <var>B</var> and <var>C</var> to match (using <var>B</var>'s <a href=#sl-candidate-nvs-hint id=speculation-rules-processing-model:sl-candidate-nvs-hint-10>No-Vary-Search hint</a>). But it could not consider
   <var>A</var> and <var>C</var> to match, so it would not be transitive, and thus not an
   equivalence relation.</p>
  </div>

  <hr>

  <p>Every <code id=speculation-rules-processing-model:document><a href=dom.html#document>Document</a></code> has <dfn id=document-sr-sets>speculation rule sets</dfn>, a
  <a id=speculation-rules-processing-model:list href=https://infra.spec.whatwg.org/#list data-x-internal=list>list</a> of <a href=#speculation-rule-set id=speculation-rules-processing-model:speculation-rule-set-2>speculation rule sets</a>, initially
  empty.</p>

  <p>Every <code id=speculation-rules-processing-model:document-2><a href=dom.html#document>Document</a></code> has a <dfn id=consider-speculative-loads-microtask-queued>consider speculative loads microtask queued</dfn>, a
  boolean, initially false.</p>

  <p>To <dfn id=consider-speculative-loads>consider speculative loads</dfn> for a <code id=speculation-rules-processing-model:document-3><a href=dom.html#document>Document</a></code> <var>document</var>:</p>

  <ol><li id=step-consider-speculative-loads-top-level-only>
    <p>If <var>document</var>'s <a id=speculation-rules-processing-model:node-navigable href=document-sequences.html#node-navigable>node navigable</a> is not a <a id=speculation-rules-processing-model:top-level-traversable href=document-sequences.html#top-level-traversable>top-level
    traversable</a>, then return.</p>

    <p class=note>Supporting speculative loads into <a href=document-sequences.html#child-navigable id=speculation-rules-processing-model:child-navigable>child
    navigables</a> has some complexities and is not currently defined. It might be possible to
    define it in the future.</p>
   <li><p>If <var>document</var>'s <a href=#consider-speculative-loads-microtask-queued id=speculation-rules-processing-model:consider-speculative-loads-microtask-queued>consider speculative loads microtask queued</a> is true,
   then return.<li><p>Set <var>document</var>'s <a href=#consider-speculative-loads-microtask-queued id=speculation-rules-processing-model:consider-speculative-loads-microtask-queued-2>consider speculative loads microtask queued</a> to
   true.<li>
    <p><a id=speculation-rules-processing-model:queue-a-microtask href=webappapis.html#queue-a-microtask>Queue a microtask</a> given <var>document</var> to run the following steps:</p>

    <ol><li><p>Set <var>document</var>'s <a href=#consider-speculative-loads-microtask-queued id=speculation-rules-processing-model:consider-speculative-loads-microtask-queued-3>consider speculative loads microtask queued</a> to
     false.<li><p>Run the <a href=#inner-consider-speculative-loads-steps id=speculation-rules-processing-model:inner-consider-speculative-loads-steps>inner consider speculative loads steps</a> for
     <var>document</var>.</ol>
   </ol>

  <p>In addition to the call sites explicitly given in this standard:</p>

  <ul><li><p>When style recalculation would cause selector matching results to change, the user agent
   must <a href=#consider-speculative-loads id=speculation-rules-processing-model:consider-speculative-loads>consider speculative loads</a> for the relevant <code id=speculation-rules-processing-model:document-4><a href=dom.html#document>Document</a></code>.<li>
    <p>When the user indicates interest in <a href=links.html#hyperlink id=speculation-rules-processing-model:hyperlink>hyperlinks</a>, in one of the
    <a id=speculation-rules-processing-model:implementation-defined href=https://infra.spec.whatwg.org/#implementation-defined data-x-internal=implementation-defined>implementation-defined</a> ways that the user agent uses to implement the
    <a href=#speculation-rule-eagerness id=speculation-rules-processing-model:speculation-rule-eagerness-2>speculation rule eagerness</a> heuristics, the user agent may <a href=#consider-speculative-loads id=speculation-rules-processing-model:consider-speculative-loads-2>consider
    speculative loads</a> for the hyperlink's <a id=speculation-rules-processing-model:node-document href=https://dom.spec.whatwg.org/#concept-node-document data-x-internal=node-document>node document</a>.</p>

    <p class=example>For example, a user agent which implements "<code id=speculation-rules-processing-model:sr-eagerness-conservative><a href=#sr-eagerness-conservative>conservative</a></code>" eagerness by watching for <code id=speculation-rules-processing-model:event-pointerdown><a data-x-internal=event-pointerdown href=https://w3c.github.io/pointerevents/#the-pointerdown-event>pointerdown</a></code> events would want to <a href=#consider-speculative-loads id=speculation-rules-processing-model:consider-speculative-loads-3>consider speculative
    loads</a> as part of reacting to such events.</p>
   </ul>

  <div id=note-consider-speculative-loads-stateless class=note><a href=#note-consider-speculative-loads-stateless class=self-link></a>
   <p>In this standard, every call to <a href=#consider-speculative-loads id=speculation-rules-processing-model:consider-speculative-loads-4>consider speculative loads</a> is given just a
   <code id=speculation-rules-processing-model:document-5><a href=dom.html#document>Document</a></code>, and the algorithm re-computes all possible candidates in a stateless way.
   A real implementation would likely cache previous computations, and pass along information from
   the call site to make updates more efficient. For example, if an <code id=speculation-rules-processing-model:the-a-element><a href=text-level-semantics.html#the-a-element>a</a></code> element's <code id=speculation-rules-processing-model:attr-hyperlink-href><a href=links.html#attr-hyperlink-href>href</a></code> attribute is changed, that specific element could be
   passed along in order to update only the related <a href=#speculative-load-candidate id=speculation-rules-processing-model:speculative-load-candidate-5>speculative load candidate</a>.</p>

   <p>Note that because of how <a href=#consider-speculative-loads id=speculation-rules-processing-model:consider-speculative-loads-5>consider speculative loads</a> queues a microtask, by the
   time the <a href=#inner-consider-speculative-loads-steps id=speculation-rules-processing-model:inner-consider-speculative-loads-steps-2>inner consider speculative loads steps</a> are run, multiple updates (or <a href=#step-prefetch-record-cancel-and-discard>cancelations</a>) might be processed
   together.</p>
  </div>

  <p>The <dfn id=inner-consider-speculative-loads-steps>inner consider speculative loads steps</dfn> for a <code id=speculation-rules-processing-model:document-6><a href=dom.html#document>Document</a></code>
  <var>document</var> are:</p>

  <ol><li><p>If <var>document</var> is not <a id=speculation-rules-processing-model:fully-active href=document-sequences.html#fully-active>fully active</a>, then return.<li><p>Let <var>prefetchCandidates</var> be an empty <a id=speculation-rules-processing-model:list-2 href=https://infra.spec.whatwg.org/#list data-x-internal=list>list</a>.<li>
    <p><a href=https://infra.spec.whatwg.org/#list-iterate id=speculation-rules-processing-model:list-iterate data-x-internal=list-iterate>For each</a> <var>ruleSet</var> of <var>document</var>'s <a href=#document-sr-sets id=speculation-rules-processing-model:document-sr-sets>speculation rule sets</a>:</p>

    <ol><li>
      <p><a href=https://infra.spec.whatwg.org/#list-iterate id=speculation-rules-processing-model:list-iterate-2 data-x-internal=list-iterate>For each</a> <var>rule</var> of <var>ruleSet</var>'s <a href=#sr-set-prefetch id=speculation-rules-processing-model:sr-set-prefetch>prefetch rules</a>:</p>

      <ol><li><p>Let <var>anonymizationPolicy</var> be null.<li><p>If <var>rule</var>'s <a href=#sr-requirements id=speculation-rules-processing-model:sr-requirements>requirements</a> <a href=https://infra.spec.whatwg.org/#list-contain id=speculation-rules-processing-model:list-contains data-x-internal=list-contains>contains</a> "<code>anonymous-client-ip-when-cross-origin</code>", then set
       <var>anonymizationPolicy</var> to a <a href=#cross-origin-prefetch-ip-anonymization-policy id=speculation-rules-processing-model:cross-origin-prefetch-ip-anonymization-policy-2>cross-origin prefetch IP anonymization
       policy</a> whose <a href=#copiap-origin id=speculation-rules-processing-model:copiap-origin>origin</a> is <var>document</var>'s <a href=https://dom.spec.whatwg.org/#concept-document-origin id=speculation-rules-processing-model:concept-document-origin data-x-internal=concept-document-origin>origin</a>.<li>
        <p><a href=https://infra.spec.whatwg.org/#list-iterate id=speculation-rules-processing-model:list-iterate-3 data-x-internal=list-iterate>For each</a> <var>url</var> of <var>rule</var>'s <a href=#sr-urls id=speculation-rules-processing-model:sr-urls>URLs</a>:</p>

        <ol><li><p>Let <var>referrerPolicy</var> be the result of <a href=#compute-a-speculative-load-referrer-policy id=speculation-rules-processing-model:compute-a-speculative-load-referrer-policy>computing a speculative load referrer policy</a> given
         <var>rule</var> and null.<li>
          <p><a href=https://infra.spec.whatwg.org/#list-append id=speculation-rules-processing-model:list-append data-x-internal=list-append>Append</a> a new <a href=#prefetch-candidate id=speculation-rules-processing-model:prefetch-candidate>prefetch candidate</a> with</p>

          <dl class=props><dt><a href=#sl-candidate-url id=speculation-rules-processing-model:sl-candidate-url-6>URL</a><dd><var>url</var><dt><a href=#sl-candidate-nvs-hint id=speculation-rules-processing-model:sl-candidate-nvs-hint-11>No-Vary-Search hint</a><dd><var>rule</var>'s <a href=#sr-nvs-hint id=speculation-rules-processing-model:sr-nvs-hint>No-Vary-Search hint</a><dt><a href=#sl-candidate-eagerness id=speculation-rules-processing-model:sl-candidate-eagerness>eagerness</a><dd><var>rule</var>'s <a href=#sr-eagerness id=speculation-rules-processing-model:sr-eagerness>eagerness</a><dt><a href=#sl-candidate-referrer-policy id=speculation-rules-processing-model:sl-candidate-referrer-policy>referrer policy</a><dd><var>referrerPolicy</var><dt><a href=#sl-candidate-tags id=speculation-rules-processing-model:sl-candidate-tags>tags</a><dd><var>rule</var>'s <a href=#sr-tags id=speculation-rules-processing-model:sr-tags>tags</a><dt><a href=#sl-candidate-anonymization-policy id=speculation-rules-processing-model:sl-candidate-anonymization-policy>anonymization policy</a><dd><var>anonymizationPolicy</var></dl>

          <p>to <var>prefetchCandidates</var>.</p>
         </ol>
       <li>
        <p>If <var>rule</var>'s <a href=#sr-predicate id=speculation-rules-processing-model:sr-predicate>predicate</a> is not null:</p>

        <ol><li><p>Let <var>links</var> be the result of <a href=#find-matching-links id=speculation-rules-processing-model:find-matching-links>finding
         matching links</a> given <var>document</var> and <var>rule</var>'s <a href=#sr-predicate id=speculation-rules-processing-model:sr-predicate-2>predicate</a>.<li>
          <p><a href=https://infra.spec.whatwg.org/#list-iterate id=speculation-rules-processing-model:list-iterate-4 data-x-internal=list-iterate>For each</a> <var>link</var> of <var>links</var>:</p>

          <ol><li><p>Let <var>referrerPolicy</var> be the result of <a href=#compute-a-speculative-load-referrer-policy id=speculation-rules-processing-model:compute-a-speculative-load-referrer-policy-2>computing a speculative load referrer policy</a> given
           <var>rule</var> and <var>link</var>.<li>
            <p><a href=https://infra.spec.whatwg.org/#list-append id=speculation-rules-processing-model:list-append-2 data-x-internal=list-append>Append</a> a new <a href=#prefetch-candidate id=speculation-rules-processing-model:prefetch-candidate-2>prefetch candidate</a>
            with</p>

            <dl class=props><dt><a href=#sl-candidate-url id=speculation-rules-processing-model:sl-candidate-url-7>URL</a><dd><var>link</var>'s <a href=links.html#concept-hyperlink-url id=speculation-rules-processing-model:concept-hyperlink-url>url</a><dt><a href=#sl-candidate-nvs-hint id=speculation-rules-processing-model:sl-candidate-nvs-hint-12>No-Vary-Search hint</a><dd><var>rule</var>'s <a href=#sr-nvs-hint id=speculation-rules-processing-model:sr-nvs-hint-2>No-Vary-Search hint</a><dt><a href=#sl-candidate-eagerness id=speculation-rules-processing-model:sl-candidate-eagerness-2>eagerness</a><dd><var>rule</var>'s <a href=#sr-eagerness id=speculation-rules-processing-model:sr-eagerness-2>eagerness</a><dt><a href=#sl-candidate-referrer-policy id=speculation-rules-processing-model:sl-candidate-referrer-policy-2>referrer policy</a><dd><var>referrerPolicy</var><dt><a href=#sl-candidate-tags id=speculation-rules-processing-model:sl-candidate-tags-2>tags</a><dd><var>rule</var>'s <a href=#sr-tags id=speculation-rules-processing-model:sr-tags-2>tags</a><dt><a href=#sl-candidate-anonymization-policy id=speculation-rules-processing-model:sl-candidate-anonymization-policy-2>anonymization policy</a><dd><var>anonymizationPolicy</var></dl>

            <p>to <var>prefetchCandidates</var>.</p>
           </ol>
         </ol>
       </ol>
     </ol>
   <li id=step-prefetch-record-cancel-and-discard>
    <p><a href=https://infra.spec.whatwg.org/#list-iterate id=speculation-rules-processing-model:list-iterate-5 data-x-internal=list-iterate>For each</a> <var>prefetchRecord</var> of
    <var>document</var>'s <a href=https://wicg.github.io/nav-speculation/prefetch.html#document-prefetch-records id=speculation-rules-processing-model:document-prefetch-records data-x-internal=document-prefetch-records>prefetch records</a>:</p>

    <ol><li><p>If <var>prefetchRecord</var>'s <a href=https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-source id=speculation-rules-processing-model:prefetch-record-source data-x-internal=prefetch-record-source>source</a> is
     not "<code>speculation rules</code>", then <a id=speculation-rules-processing-model:continue href=https://infra.spec.whatwg.org/#iteration-continue data-x-internal=continue>continue</a>.<li><p><a id=speculation-rules-processing-model:assert href=https://infra.spec.whatwg.org/#assert data-x-internal=assert>Assert</a>: <var>prefetchRecord</var>'s <a href=https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-state id=speculation-rules-processing-model:prefetch-record-state data-x-internal=prefetch-record-state>state</a> is not "<code>canceled</code>".<li><p>If <var>prefetchRecord</var> is not <a id=speculation-rules-processing-model:still-being-speculated href=https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-still-being-speculated data-x-internal=still-being-speculated>still being speculated</a> given
     <var>prefetchCandidates</var>, then <a href=https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-cancel-and-discard id=speculation-rules-processing-model:prefetch-record-cancel-and-discard data-x-internal=prefetch-record-cancel-and-discard>cancel
     and discard</a> <var>prefetchRecord</var> given <var>document</var>.</ol>
   <li><p>Let <var>prefetchCandidateGroups</var> be an empty <a id=speculation-rules-processing-model:list-3 href=https://infra.spec.whatwg.org/#list data-x-internal=list>list</a>.<li>
    <p><a href=https://infra.spec.whatwg.org/#list-iterate id=speculation-rules-processing-model:list-iterate-6 data-x-internal=list-iterate>For each</a> <var>candidate</var> of
    <var>prefetchCandidates</var>:</p>

    <ol><li><p>Let <var>group</var> be « <var>candidate</var> ».<li><p><a href=https://infra.spec.whatwg.org/#list-extend id=speculation-rules-processing-model:list-extend data-x-internal=list-extend>Extend</a> <var>group</var> with all <a href=https://infra.spec.whatwg.org/#list-item id=speculation-rules-processing-model:list-item data-x-internal=list-item>items</a> in <var>prefetchCandidates</var>, apart from <var>candidate</var> itself,
     which are <a href=#sl-candidate-redundant-with id=speculation-rules-processing-model:sl-candidate-redundant-with-2>redundant with</a> <var>candidate</var>
     and whose <a href=#sl-candidate-eagerness id=speculation-rules-processing-model:sl-candidate-eagerness-3>eagerness</a> is <a href=#sr-eagerness-at-least-as-eager id=speculation-rules-processing-model:sr-eagerness-at-least-as-eager>at least as eager</a> as <var>candidate</var>'s
     <a href=#sl-candidate-eagerness id=speculation-rules-processing-model:sl-candidate-eagerness-4>eagerness</a>.<li><p>If <var>prefetchCandidateGroups</var> <a href=https://infra.spec.whatwg.org/#list-contain id=speculation-rules-processing-model:list-contains-2 data-x-internal=list-contains>contains</a>
     another group whose <a href=https://infra.spec.whatwg.org/#list-item id=speculation-rules-processing-model:list-item-2 data-x-internal=list-item>items</a> are the same as <var>group</var>,
     ignoring order, then <a id=speculation-rules-processing-model:continue-2 href=https://infra.spec.whatwg.org/#iteration-continue data-x-internal=continue>continue</a>.<li><p><a href=https://infra.spec.whatwg.org/#list-append id=speculation-rules-processing-model:list-append-3 data-x-internal=list-append>Append</a> <var>group</var> to
     <var>prefetchCandidateGroups</var>.</ol>

    <div id=example-redundant-speculation-rules class=example><a href=#example-redundant-speculation-rules class=self-link></a>
     <p>The following speculation rules generate two <a href=#sl-candidate-redundant-with id=speculation-rules-processing-model:sl-candidate-redundant-with-3>redundant</a> <a href=#prefetch-candidate id=speculation-rules-processing-model:prefetch-candidate-3>prefetch candidates</a>:</p>

     <pre><code class='json'><c- p>{</c->
  <c- u>&quot;prefetch&quot;</c-><c- o>:</c-> <c- p>[</c->
    <c- p>{</c->
      <c- u>&quot;tag&quot;</c-><c- o>:</c-> <c- u>&quot;a&quot;</c-><c- p>,</c->
      <c- u>&quot;urls&quot;</c-><c- o>:</c-> <c- p>[</c-><c- u>&quot;next.html&quot;</c-><c- p>]</c->
    <c- p>},</c->
    <c- p>{</c->
      <c- u>&quot;tag&quot;</c-><c- o>:</c-> <c- u>&quot;b&quot;</c-><c- p>,</c->
      <c- u>&quot;urls&quot;</c-><c- o>:</c-> <c- p>[</c-><c- u>&quot;next.html&quot;</c-><c- p>],</c->
      <c- u>&quot;referrer_policy&quot;</c-><c- o>:</c-> <c- u>&quot;no-referrer&quot;</c->
    <c- p>}</c->
  <c- p>]</c->
<c- p>}</c-></code></pre>

     <p>This step will create a single group containing them both, in the given order. (The second
     pass through will not create a group, since its contents would be the same as the first group,
     just in a different order.) This means that if the user agent chooses to execute the "may" step
     below to enact the group, it will enact the first candidate, and ignore the second. Thus, the
     request will be made with the <a id=speculation-rules-processing-model:default-referrer-policy href=https://w3c.github.io/webappsec-referrer-policy/#default-referrer-policy data-x-internal=default-referrer-policy>default referrer policy</a>, instead of using "<code id=speculation-rules-processing-model:referrer-policy-no-referrer><a data-x-internal=referrer-policy-no-referrer href=https://w3c.github.io/webappsec-referrer-policy/#referrer-policy-no-referrer>no-referrer</a></code>".</p>

     <p>However, the <a href=#collect-tags-from-speculative-load-candidates id=speculation-rules-processing-model:collect-tags-from-speculative-load-candidates>collect tags from speculative load candidates</a> algorithm will
     collect tags from both candidates in the group, so the `<code id=speculation-rules-processing-model:sec-speculation-tags><a href=#sec-speculation-tags>Sec-Speculation-Tags</a></code>`
     header value will be `<code>"a", "b"</code>`. This indicates to server operators that
     either rule could have caused the speculative load.</p>
    </div>
   <li>
    <p><a href=https://infra.spec.whatwg.org/#list-iterate id=speculation-rules-processing-model:list-iterate-7 data-x-internal=list-iterate>For each</a> <var>group</var> of
    <var>prefetchCandidateGroups</var>:</p>

    <ol><li>
      <p>The user agent may run the following steps:</p>

      <ol><li><p>Let <var>prefetchCandidate</var> be <var>group</var>[0].<li><p>Let <var>tagsToSend</var> be the result of <a href=#collect-tags-from-speculative-load-candidates id=speculation-rules-processing-model:collect-tags-from-speculative-load-candidates-2>collecting tags from speculative load candidates</a> given
       <var>group</var>.<li>
        <p>Let <var>prefetchRecord</var> be a new <a id=speculation-rules-processing-model:prefetch-record href=https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record data-x-internal=prefetch-record>prefetch record</a> with</p>

        <dl class=props><dt><a href=https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-source id=speculation-rules-processing-model:prefetch-record-source-2 data-x-internal=prefetch-record-source>source</a><dd>"<code>speculation rules</code>"<dt><a href=https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-url id=speculation-rules-processing-model:prefetch-record-url data-x-internal=prefetch-record-url>URL</a><dd><var>prefetchCandidate</var>'s <a href=#sl-candidate-url id=speculation-rules-processing-model:sl-candidate-url-8>URL</a><dt><a href=https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-no-vary-search-hint id=speculation-rules-processing-model:prefetch-record-nvs-hint data-x-internal=prefetch-record-nvs-hint>No-Vary-Search hint</a><dd><var>prefetchCandidate</var>'s <a href=#sl-candidate-nvs-hint id=speculation-rules-processing-model:sl-candidate-nvs-hint-13>No-Vary-Search
         hint</a><dt><a href=https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-referrer-policy id=speculation-rules-processing-model:prefetch-record-referrer-policy data-x-internal=prefetch-record-referrer-policy>referrer policy</a><dd><var>prefetchCandidate</var>'s <a href=#sl-candidate-referrer-policy id=speculation-rules-processing-model:sl-candidate-referrer-policy-3>referrer
         policy</a><dt><a href=https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-anonymization-policy id=speculation-rules-processing-model:prefetch-record-anonymization-policy data-x-internal=prefetch-record-anonymization-policy>anonymization policy</a><dd><var>prefetchCandidate</var>'s <a href=#sl-candidate-anonymization-policy id=speculation-rules-processing-model:sl-candidate-anonymization-policy-3>anonymization policy</a><dt><a href=https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-tags id=speculation-rules-processing-model:prefetch-record-tags data-x-internal=prefetch-record-tags>tags</a> <dd><var>tagsToSend</var></dl>
       <li><p><a id=speculation-rules-processing-model:start-a-referrer-initiated-navigational-prefetch href=https://wicg.github.io/nav-speculation/prefetch.html#start-a-referrer-initiated-navigational-prefetch data-x-internal=start-a-referrer-initiated-navigational-prefetch>Start a referrer-initiated navigational prefetch</a> given
       <var>prefetchRecord</var> and <var>document</var>.</ol>

      <p>When deciding whether to execute this "may" step, user agents should consider
      <var>prefetchCandidate</var>'s <a href=#sl-candidate-eagerness id=speculation-rules-processing-model:sl-candidate-eagerness-5>eagerness</a>, in
      accordance to the current behavior of the user and the definitions of <a href=#speculation-rule-eagerness id=speculation-rules-processing-model:speculation-rule-eagerness-3>speculation rule
      eagerness</a>.</p>

      <p><var>prefetchCandidate</var>'s <a href=#sl-candidate-nvs-hint id=speculation-rules-processing-model:sl-candidate-nvs-hint-14>No-Vary-Search
      hint</a> can also be useful in implementing the heuristics defined for the
      <a href=#speculation-rule-eagerness id=speculation-rules-processing-model:speculation-rule-eagerness-4>speculation rule eagerness</a> values. For example, a user hovering of a link whose
      <a href=links.html#concept-hyperlink-url id=speculation-rules-processing-model:concept-hyperlink-url-2>URL</a> is <a id=speculation-rules-processing-model:equivalent-modulo-search-variance-2 href=https://httpwg.org/http-extensions/draft-ietf-httpbis-no-vary-search.html#name-comparing data-x-internal=equivalent-modulo-search-variance>equivalent modulo search
      variance</a> to <var>prefetchCandidate</var>'s <a href=#sl-candidate-url id=speculation-rules-processing-model:sl-candidate-url-9>URL</a>
      given <var>prefetchCandidate</var>'s <a href=#sl-candidate-nvs-hint id=speculation-rules-processing-model:sl-candidate-nvs-hint-15>No-Vary-Search
      hint</a> could indicate to the user agent that performing this step would be useful.</p>

      <p>When deciding whether to execute this "may" step, user agents should prioritize user
      preferences (express or implied, such as data-saver or battery-saver modes) over the eagerness
      supplied by the web developer.</p>
     </ol>
   </ol>

  <p>To <dfn id=compute-a-speculative-load-referrer-policy>compute a speculative load referrer policy</dfn> given a <a href=#speculation-rule id=speculation-rules-processing-model:speculation-rule>speculation rule</a>
  <var>rule</var> and an <code id=speculation-rules-processing-model:the-a-element-2><a href=text-level-semantics.html#the-a-element>a</a></code> element, <code id=speculation-rules-processing-model:the-area-element><a href=image-maps.html#the-area-element>area</a></code> element, or null
  <var>link</var>:</p>

  <ol><li><p>If <var>rule</var>'s <a href=#sr-referrer-policy id=speculation-rules-processing-model:sr-referrer-policy>referrer policy</a> is not the
   empty string, then return <var>rule</var>'s <a href=#sr-referrer-policy id=speculation-rules-processing-model:sr-referrer-policy-2>referrer
   policy</a>.<li><p>If <var>link</var> is null, then return the empty string.<li><p>Return <var>link</var>'s <a id=speculation-rules-processing-model:hyperlink-referrer-policy href=links.html#hyperlink-referrer-policy>hyperlink referrer policy</a>.</ol>

  <p>To <dfn id=collect-tags-from-speculative-load-candidates>collect tags from speculative load candidates</dfn> given a <a id=speculation-rules-processing-model:list-4 href=https://infra.spec.whatwg.org/#list data-x-internal=list>list</a> of <a href=#speculative-load-candidate id=speculation-rules-processing-model:speculative-load-candidate-6>speculative load candidates</a> <var>candidates</var>:</p>

  <ol><li><p>Let <var>tags</var> be an empty <a href=https://infra.spec.whatwg.org/#ordered-set id=speculation-rules-processing-model:set-2 data-x-internal=set>ordered set</a>.<li>
    <p><a href=https://infra.spec.whatwg.org/#list-iterate id=speculation-rules-processing-model:list-iterate-8 data-x-internal=list-iterate>For each</a> <var>candidate</var> of
    <var>candidates</var>:</p>

    <ol><li><p><a href=https://infra.spec.whatwg.org/#list-iterate id=speculation-rules-processing-model:list-iterate-9 data-x-internal=list-iterate>For each</a> <var>tag</var> of <var>candidate</var>'s
     <a href=#sl-candidate-tags id=speculation-rules-processing-model:sl-candidate-tags-3>tags</a>: <a href=https://infra.spec.whatwg.org/#set-append id=speculation-rules-processing-model:set-append data-x-internal=set-append>append</a>
     <var>tag</var> to <var>tags</var>.</ol>
   <li><p><a href=https://infra.spec.whatwg.org/#list-sort-in-ascending-order id=speculation-rules-processing-model:list-sort data-x-internal=list-sort>Sort in ascending order</a> <var>tags</var>, with
   <var>tagA</var> being less than <var>tagB</var> if <var>tagA</var> is null, or if <var>tagA</var>
   is <a id=speculation-rules-processing-model:code-unit-less-than href=https://infra.spec.whatwg.org/#code-unit-less-than data-x-internal=code-unit-less-than>code unit less than</a> <var>tagB</var>.<li><p>Return <var>tags</var>.</ol>

  <hr>

  <p>To <dfn id=find-matching-links>find matching links</dfn> given a <code id=speculation-rules-processing-model:document-7><a href=dom.html#document>Document</a></code> <var>document</var> and a
  <a href=#document-rule-predicate id=speculation-rules-processing-model:document-rule-predicate>document rule predicate</a> <var>predicate</var>:</p>

  <ol><li><p>Let <var>links</var> be an empty <a id=speculation-rules-processing-model:list-5 href=https://infra.spec.whatwg.org/#list data-x-internal=list>list</a>.<li>
    <p><a href=https://infra.spec.whatwg.org/#list-iterate id=speculation-rules-processing-model:list-iterate-10 data-x-internal=list-iterate>For each</a> <a id=speculation-rules-processing-model:shadow-including-descendant href=https://dom.spec.whatwg.org/#concept-shadow-including-descendant data-x-internal=shadow-including-descendant>shadow-including descendant</a>
    <var>descendant</var> of <var>document</var>, in <a id=speculation-rules-processing-model:shadow-including-tree-order href=https://dom.spec.whatwg.org/#concept-shadow-including-tree-order data-x-internal=shadow-including-tree-order>shadow-including tree order</a>:</p>

    <ol><li><p>If <var>descendant</var> is not an <code id=speculation-rules-processing-model:the-a-element-3><a href=text-level-semantics.html#the-a-element>a</a></code> or <code id=speculation-rules-processing-model:the-area-element-2><a href=image-maps.html#the-area-element>area</a></code> element with an
     <code id=speculation-rules-processing-model:attr-hyperlink-href-2><a href=links.html#attr-hyperlink-href>href</a></code> attribute, then <a id=speculation-rules-processing-model:continue-3 href=https://infra.spec.whatwg.org/#iteration-continue data-x-internal=continue>continue</a>.<li>
      <p>If <var>descendant</var> is not <a id=speculation-rules-processing-model:being-rendered href=rendering.html#being-rendered>being rendered</a> or is part of <a href=https://drafts.csswg.org/css-contain/#skips-its-contents id=speculation-rules-processing-model:skips-its-contents data-x-internal=skips-its-contents>skipped contents</a>, then <a id=speculation-rules-processing-model:continue-4 href=https://infra.spec.whatwg.org/#iteration-continue data-x-internal=continue>continue</a>.</p>

      <p class=note>Such links, though present in <var>document</var>, aren't available for the
      user to interact with, and thus are unlikely to be good candidates. In addition, they might
      not have their style or layout computed, which might make selector matching less efficient in
      user agents which skip some or all of that work for these elements.</p>
     <li><p>If <var>descendant</var>'s <a href=links.html#concept-hyperlink-url id=speculation-rules-processing-model:concept-hyperlink-url-3>url</a> is null, or
     its <a href=https://url.spec.whatwg.org/#concept-url-scheme id=speculation-rules-processing-model:concept-url-scheme data-x-internal=concept-url-scheme>scheme</a> is not an <a id=speculation-rules-processing-model:http(s)-scheme href=https://fetch.spec.whatwg.org/#http-scheme data-x-internal=http(s)-scheme>HTTP(S) scheme</a>, then
     <a id=speculation-rules-processing-model:continue-5 href=https://infra.spec.whatwg.org/#iteration-continue data-x-internal=continue>continue</a>.<li><p>If <var>predicate</var> <a href=#dr-predicate-matches id=speculation-rules-processing-model:dr-predicate-matches>matches</a>
     <var>descendant</var>, then <a href=https://infra.spec.whatwg.org/#list-append id=speculation-rules-processing-model:list-append-4 data-x-internal=list-append>append</a> <var>descendant</var> to
     <var>links</var>.</ol>
   <li><p>Return <var>links</var>.</ol>

  <p>A <a href=#document-rule-predicate id=speculation-rules-processing-model:document-rule-predicate-2>document rule predicate</a> <var>predicate</var> <dfn id=dr-predicate-matches>matches</dfn> an <code id=speculation-rules-processing-model:the-a-element-4><a href=text-level-semantics.html#the-a-element>a</a></code> or <code id=speculation-rules-processing-model:the-area-element-3><a href=image-maps.html#the-area-element>area</a></code> element
  <var>el</var> if the following steps return true, switching on <var>predicate</var>'s type:</p>

  <dl class=switch><dt><a href=#document-rule-conjunction id=speculation-rules-processing-model:document-rule-conjunction>document rule conjunction</a><dd>
    <ol><li>
      <p><a href=https://infra.spec.whatwg.org/#list-iterate id=speculation-rules-processing-model:list-iterate-11 data-x-internal=list-iterate>For each</a> <var>clause</var> of <var>predicate</var>'s
      <a href=#sr-dr-c-clauses id=speculation-rules-processing-model:sr-dr-c-clauses>clauses</a>:</p>

      <ol><li><p>If <var>clause</var> does not <a href=#dr-predicate-matches id=speculation-rules-processing-model:dr-predicate-matches-2>match</a>
       <var>el</var>, then return false.</ol>
     <li><p>Return true.</ol>
   <dt><a href=#document-rule-disjunction id=speculation-rules-processing-model:document-rule-disjunction>document rule disjunction</a><dd>
    <ol><li>
      <p><a href=https://infra.spec.whatwg.org/#list-iterate id=speculation-rules-processing-model:list-iterate-12 data-x-internal=list-iterate>For each</a> <var>clause</var> of <var>predicate</var>'s
      <a href=#sr-dr-d-clauses id=speculation-rules-processing-model:sr-dr-d-clauses>clauses</a>:</p>

      <ol><li><p>If <var>clause</var> <a href=#dr-predicate-matches id=speculation-rules-processing-model:dr-predicate-matches-3>matches</a> <var>el</var>,
       then return true.</ol>
     <li><p>Return false.</ol>
   <dt><a href=#document-rule-negation id=speculation-rules-processing-model:document-rule-negation>document rule negation</a><dd>
    <ol><li><p>If <var>predicate</var>'s <a href=#sr-dr-n-clause id=speculation-rules-processing-model:sr-dr-n-clause>clause</a> <a href=#dr-predicate-matches id=speculation-rules-processing-model:dr-predicate-matches-4>matches</a> <var>el</var>, then return false.<li><p>Return true.</ol>
   <dt><a href=#document-rule-url-pattern-predicate id=speculation-rules-processing-model:document-rule-url-pattern-predicate>document rule URL pattern predicate</a><dd>
    <ol><li>
      <p><a href=https://infra.spec.whatwg.org/#list-iterate id=speculation-rules-processing-model:list-iterate-13 data-x-internal=list-iterate>For each</a> <var>pattern</var> of <var>predicate</var>'s
      <a href=#sr-dr-urlpattern-patterns id=speculation-rules-processing-model:sr-dr-urlpattern-patterns>patterns</a>:</p>

      <ol><li><p>If performing a <a href=https://urlpattern.spec.whatwg.org/#url-pattern-match id=speculation-rules-processing-model:url-pattern-match data-x-internal=url-pattern-match>match</a> given <var>pattern</var>
       and <var>el</var>'s <a href=links.html#concept-hyperlink-url id=speculation-rules-processing-model:concept-hyperlink-url-4>url</a> gives a non-null value,
       then return true.</ol>
     <li><p>Return false.</ol>
   <dt><a href=#document-rule-selector-predicate id=speculation-rules-processing-model:document-rule-selector-predicate>document rule selector predicate</a><dd>
    <ol><li>
      <p><a href=https://infra.spec.whatwg.org/#list-iterate id=speculation-rules-processing-model:list-iterate-14 data-x-internal=list-iterate>For each</a> <var>selector</var> of <var>predicate</var>'s
      <a href=#sr-dr-cssselector-selectors id=speculation-rules-processing-model:sr-dr-cssselector-selectors>selectors</a>:</p>

      <ol><li><p>If performing a <a href=https://drafts.csswg.org/selectors/#match-a-selector-against-an-element id=speculation-rules-processing-model:match-a-selector-against-an-element data-x-internal=match-a-selector-against-an-element>match</a> given
       <var>selector</var> and <var>el</var> with the <a id=speculation-rules-processing-model:scoping-root href=https://drafts.csswg.org/selectors/#scoping-root data-x-internal=scoping-root>scoping root</a> set to
       <var>el</var>'s <a id=speculation-rules-processing-model:root href=https://dom.spec.whatwg.org/#concept-tree-root data-x-internal=root>root</a> returns sucess, then return true.</ol>
     <li><p>Return false.</ol>
   </dl>

  <hr>

  <p>Speculation rules features use the <dfn id=speculation-rules-task-source>speculation rules task source</dfn>, which is a
  <a id=speculation-rules-processing-model:task-source href=webappapis.html#task-source>task source</a>.</p>

  <p class=note>Because speculative loading is generally less important than processing tasks for
  the purpose of the current document, implementations might give <a href=webappapis.html#concept-task id=speculation-rules-processing-model:concept-task>tasks</a> enqueued here an especially low priority.</p>

  <h4 id=navigational-prefetching><span class=secno>7.6.2</span> Navigational prefetching<a href=#navigational-prefetching class=self-link></a></h4>

  <p>For now, the navigational prefetching process is defined in the <cite>Prefetch</cite>
  specification. Moving it into this standard is tracked in <a href=https://github.com/whatwg/html/issues/11123>issue #11123</a>. <a href=references.html#refsPREFETCH>[PREFETCH]</a></p>

  <p>This standard refers to the following concepts defined there:</p>

  <ul class=brief><li><dfn id=prefetch-record><a href=https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record>prefetch
   record</a></dfn>, and its items <dfn id=prefetch-record-source><a href=https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-source>source</a></dfn>,
   <dfn id=prefetch-record-url><a href=https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-url>URL</a></dfn>,
   <dfn id=prefetch-record-nvs-hint><a href=https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-no-vary-search-hint>No-Vary-Search
   hint</a></dfn>, <dfn id=prefetch-record-referrer-policy><a href=https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-referrer-policy>referrer
   policy</a></dfn>, <dfn id=prefetch-record-anonymization-policy><a href=https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-anonymization-policy>anonymization
   policy</a></dfn>, <dfn id=prefetch-record-tags><a href=https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-tags>tags</a></dfn>,
   and <dfn id=prefetch-record-state><a href=https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-state>state</a></dfn><li><dfn id=prefetch-record-cancel-and-discard><a href=https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-cancel-and-discard>cancel
   and discard</a></dfn><li><dfn id=still-being-speculated><a href=https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-still-being-speculated>still
   being speculated</a></dfn><li><dfn id=document-prefetch-records><a href=https://wicg.github.io/nav-speculation/prefetch.html#document-prefetch-records>prefetch
   records</a></dfn><li><dfn id=start-a-referrer-initiated-navigational-prefetch><a href=https://wicg.github.io/nav-speculation/prefetch.html#start-a-referrer-initiated-navigational-prefetch>start
   a referrer-initiated navigational prefetch</a></dfn></ul>

  <h4 id=the-speculation-rules-header><span class=secno>7.6.3</span> The `<code id=the-speculation-rules-header:speculation-rules-2><a href=#speculation-rules-2>Speculation-Rules</a></code>` header<a href=#the-speculation-rules-header class=self-link></a></h4>

  <p>The `<dfn id=speculation-rules-2 data-dfn-type=http-header><code>Speculation-Rules</code></dfn>` HTTP response header allows the
  developer to request that the user agent fetch and apply a given <a href=#speculation-rule-set id=the-speculation-rules-header:speculation-rule-set>speculation rule set</a>
  to the current <code id=the-speculation-rules-header:document><a href=dom.html#document>Document</a></code>. It is a <a href=https://httpwg.org/specs/rfc8941.html id=the-speculation-rules-header:http-structured-header data-x-internal=http-structured-header>structured
  header</a> whose value must be a <a href=https://httpwg.org/specs/rfc8941.html#list id=the-speculation-rules-header:http-structured-header-list data-x-internal=http-structured-header-list>list</a> of
  <a href=https://httpwg.org/specs/rfc8941.html#string id=the-speculation-rules-header:http-structured-header-string data-x-internal=http-structured-header-string>strings</a> that are all <a href=https://url.spec.whatwg.org/#valid-url-string id=the-speculation-rules-header:valid-url-string data-x-internal=valid-url-string>valid URL strings</a>.</p>

  <p>To <dfn id=process-the-speculation-rules-header>process the `<code>Speculation-Rules</code>` header</dfn> given a <code id=the-speculation-rules-header:document-2><a href=dom.html#document>Document</a></code>
  <var>document</var> and a <a href=https://fetch.spec.whatwg.org/#concept-response id=the-speculation-rules-header:concept-response data-x-internal=concept-response>response</a> <var>response</var>:</p>

  <ol><li><p>Let <var>parsedList</var> be the result of <a id=the-speculation-rules-header:getting-a-structured-field-value href=https://fetch.spec.whatwg.org/#concept-header-list-get-structured-header data-x-internal=getting-a-structured-field-value>getting a structured field value</a>
   given `<code id=the-speculation-rules-header:speculation-rules-2-2><a href=#speculation-rules-2>Speculation-Rules</a></code>` and "<code>list</code>" from
   <var>response</var>'s <a href=https://fetch.spec.whatwg.org/#concept-response-header-list id=the-speculation-rules-header:concept-response-header-list data-x-internal=concept-response-header-list>header list</a>.<li><p>If <var>parsedList</var> is null, then return.<li>
    <p><a href=https://infra.spec.whatwg.org/#list-iterate id=the-speculation-rules-header:list-iterate data-x-internal=list-iterate>For each</a> <var>item</var> of <var>parsedList</var>:</p>

    <ol><li><p>If <var>item</var> is not a <a id=the-speculation-rules-header:string href=https://infra.spec.whatwg.org/#string data-x-internal=string>string</a>, then <a id=the-speculation-rules-header:continue href=https://infra.spec.whatwg.org/#iteration-continue data-x-internal=continue>continue</a>.<li><p>Let <var>url</var> be the result of <a href=https://url.spec.whatwg.org/#concept-url-parser id=the-speculation-rules-header:url-parser data-x-internal=url-parser>URL parsing</a>
     <var>item</var> with <var>document</var>'s <a id=the-speculation-rules-header:document-base-url href=urls-and-fetching.html#document-base-url>document base URL</a>.<li><p>If <var>url</var> is failure, then <a id=the-speculation-rules-header:continue-2 href=https://infra.spec.whatwg.org/#iteration-continue data-x-internal=continue>continue</a>.<li>
      <p><a id=the-speculation-rules-header:in-parallel href=infrastructure.html#in-parallel>In parallel</a>:</p>

      <ol><li>
        <p>Optionally, wait for an <a id=the-speculation-rules-header:implementation-defined href=https://infra.spec.whatwg.org/#implementation-defined data-x-internal=implementation-defined>implementation-defined</a> amount of time.</p>

        <p class=note>This allows the implementation to prioritize other work ahead of loading
        speculation rules, as especially during <code id=the-speculation-rules-header:document-3><a href=dom.html#document>Document</a></code> creation and header
        processing, there are often many more important things going on.</p>
       <li>
        <p><a id=the-speculation-rules-header:queue-a-global-task href=webappapis.html#queue-a-global-task>Queue a global task</a> on the <a href=#speculation-rules-task-source id=the-speculation-rules-header:speculation-rules-task-source>speculation rules task source</a> given
        <var>document</var>'s <a id=the-speculation-rules-header:concept-relevant-global href=webappapis.html#concept-relevant-global>relevant global object</a> to perform the following
        steps:</p>

        <ol><li><p>Let <var>request</var> be a new <a href=https://fetch.spec.whatwg.org/#concept-request id=the-speculation-rules-header:concept-request data-x-internal=concept-request>request</a> whose
         <a href=https://fetch.spec.whatwg.org/#concept-request-url id=the-speculation-rules-header:concept-request-url data-x-internal=concept-request-url>URL</a> is <var>url</var>, <a href=https://fetch.spec.whatwg.org/#concept-request-destination id=the-speculation-rules-header:concept-request-destination data-x-internal=concept-request-destination>destination</a> is "<code>speculationrules</code>", and <a href=https://fetch.spec.whatwg.org/#concept-request-mode id=the-speculation-rules-header:concept-request-mode data-x-internal=concept-request-mode>mode</a> is
         "<code>cors</code>".<li>
          <p><a href=https://fetch.spec.whatwg.org/#concept-fetch id=the-speculation-rules-header:concept-fetch data-x-internal=concept-fetch>Fetch</a> <var>request</var> with the following <i id=the-speculation-rules-header:processresponseconsumebody><a data-x-internal=processresponseconsumebody href=https://fetch.spec.whatwg.org/#process-response-end-of-body>processResponseConsumeBody</a></i> steps given <a href=https://fetch.spec.whatwg.org/#concept-response id=the-speculation-rules-header:concept-response-2 data-x-internal=concept-response>response</a> <var>response</var> and null, failure, or a
          <a id=the-speculation-rules-header:byte-sequence href=https://infra.spec.whatwg.org/#byte-sequence data-x-internal=byte-sequence>byte sequence</a> <var>bodyBytes</var>:</p>

          <ol><li><p>If <var>bodyBytes</var> is null or failure, then abort these steps.<li><p>If <var>response</var>'s <a href=https://fetch.spec.whatwg.org/#concept-response-status id=the-speculation-rules-header:concept-response-status data-x-internal=concept-response-status>status</a> is
           not an <a id=the-speculation-rules-header:ok-status href=https://fetch.spec.whatwg.org/#ok-status data-x-internal=ok-status>ok status</a>, then abort these steps.<li><p>If the result of <a href=https://fetch.spec.whatwg.org/#concept-header-extract-mime-type id=the-speculation-rules-header:extract-a-mime-type data-x-internal=extract-a-mime-type>extracting a MIME type</a>
           from <var>response</var>'s <a href=https://fetch.spec.whatwg.org/#concept-response-header-list id=the-speculation-rules-header:concept-response-header-list-2 data-x-internal=concept-response-header-list>header list</a>
           does not have an <a href=https://mimesniff.spec.whatwg.org/#mime-type-essence id=the-speculation-rules-header:mime-type-essence data-x-internal=mime-type-essence>essence</a> of
           "<code id=the-speculation-rules-header:application/speculationrules+json><a href=iana.html#application/speculationrules+json>application/speculationrules+json</a></code>", then abort these steps.<li><p>Let <var>bodyText</var> be the result of <a href=https://encoding.spec.whatwg.org/#utf-8-decode id=the-speculation-rules-header:utf-8-decode data-x-internal=utf-8-decode>UTF-8
           decoding</a> <var>bodyBytes</var>.<li><p>Let <var>ruleSet</var> be the result of <a href=#parse-a-speculation-rule-set-string id=the-speculation-rules-header:parse-a-speculation-rule-set-string>parsing a speculation rule set string</a> given <var>bodyText</var>,
           <var>document</var>, and <var>response</var>'s <a href=https://fetch.spec.whatwg.org/#concept-response-url id=the-speculation-rules-header:concept-response-url data-x-internal=concept-response-url>URL</a>. If this throws an exception, then abort these
           steps.<li><p><a href=https://infra.spec.whatwg.org/#list-append id=the-speculation-rules-header:list-append data-x-internal=list-append>Append</a> <var>ruleSet</var> to
           <var>document</var>'s <a href=#document-sr-sets id=the-speculation-rules-header:document-sr-sets>speculation rule
           sets</a>.<li><p><a href=#consider-speculative-loads id=the-speculation-rules-header:consider-speculative-loads>Consider speculative loads</a> for <var>document</var>.</ol>
         </ol>
       </ol>
     </ol>
   </ol>


  <h4 id=the-sec-speculation-tags-header><span class=secno>7.6.4</span> The `<code id=the-sec-speculation-tags-header:sec-speculation-tags><a href=#sec-speculation-tags>Sec-Speculation-Tags</a></code>` header<a href=#the-sec-speculation-tags-header class=self-link></a></h4>

  <p>The `<dfn id=sec-speculation-tags data-dfn-type=http-header><code>Sec-Speculation-Tags</code></dfn>` HTTP request header specifies
  the web developer-provided tags associated with the speculative navigation request. It can also be
  used to distinguish speculative navigation requests from speculative subresource requests, since
  `<code id=the-sec-speculation-tags-header:sec-purpose><a data-x-internal=sec-purpose href=https://fetch.spec.whatwg.org/#sec-purpose-header>Sec-Purpose</a></code>` can be sent by both categories of requests.</p>

  <p>The header is a <a href=https://httpwg.org/specs/rfc8941.html id=the-sec-speculation-tags-header:http-structured-header data-x-internal=http-structured-header>structured header</a> whose value must
  be a <a href=https://httpwg.org/specs/rfc8941.html#list id=the-sec-speculation-tags-header:http-structured-header-list data-x-internal=http-structured-header-list>list</a>. The list can contain either <a href=https://httpwg.org/specs/rfc8941.html#token id=the-sec-speculation-tags-header:http-structured-header-token data-x-internal=http-structured-header-token>token</a> or <a href=https://httpwg.org/specs/rfc8941.html#string id=the-sec-speculation-tags-header:http-structured-header-string data-x-internal=http-structured-header-string>string</a> values. String values represent
  developer-provided tags, whereas token values represent predefined tags. As of now, the only
  predefined tag is <code>null</code>, which indicates a speculative navigation request
  with no developer-defined tag.</p>


  <h4 id=speculative-loading-security><span class=secno>7.6.5</span> Security considerations<a href=#speculative-loading-security class=self-link></a></h4>


  <h5 id=speculative-loading-cross-site-requests><span class=secno>7.6.5.1</span> Cross-site requests<a href=#speculative-loading-cross-site-requests class=self-link></a></h5>

  <p>Speculative loads can be initiated by web pages to cross-site destinations. However, because
  such cross-site speculative loads are always done without <a id=speculative-loading-cross-site-requests:credentials href=https://fetch.spec.whatwg.org/#credentials data-x-internal=credentials>credentials</a>, as explained
  <a href=speculative-loading-state-partitioning.html>below</a>, ambient authority is limited to
  requests that are already possible via other mechanisms on the platform.</p>

  <p>The `<code id=speculative-loading-cross-site-requests:speculation-rules-2><a href=#speculation-rules-2>Speculation-Rules</a></code>` header can also be used to issue requests, for JSON
  documents whose body will be <a href=#parse-a-speculation-rule-set-string id=speculative-loading-cross-site-requests:parse-a-speculation-rule-set-string>parsed as a
  speculation rule set string</a>. However, they use the "<code>same-origin</code>"
  <a href=https://fetch.spec.whatwg.org/#concept-request-credentials-mode id=speculative-loading-cross-site-requests:concept-request-credentials-mode data-x-internal=concept-request-credentials-mode>credentials mode</a>, the "<code>cors</code>" <a href=https://fetch.spec.whatwg.org/#concept-request-mode id=speculative-loading-cross-site-requests:concept-request-mode data-x-internal=concept-request-mode>mode</a>, and responses which do not
  use the <code id=speculative-loading-cross-site-requests:application/speculationrules+json><a href=iana.html#application/speculationrules+json>application/speculationrules+json</a></code> <a id=speculative-loading-cross-site-requests:mime-type-essence href=https://mimesniff.spec.whatwg.org/#mime-type-essence data-x-internal=mime-type-essence>MIME type essence</a> are ignored,
  so they are not useful in mounting attacks.</p>


  <h5 id=speculative-loading-injected-content><span class=secno>7.6.5.2</span> Injected content<a href=#speculative-loading-injected-content class=self-link></a></h5>

  <p>Because links in a document can be selected for speculative loading via <a href=#document-rule-predicate id=speculative-loading-injected-content:document-rule-predicate>document rule predicates</a>, developers need to be cautious if such links
  might contain user-generated markup. For example, if the <code id=speculative-loading-injected-content:attr-hyperlink-href><a href=links.html#attr-hyperlink-href>href</a></code> of a link can be entered by one user and displayed to all
  other users, a malicious user might choose a value like "<code>/logout</code>", causing
  other users' browsers to automatically log out of the site when that link is speculatively loaded.
  Using a <a href=#document-rule-selector-predicate id=speculative-loading-injected-content:document-rule-selector-predicate>document rule selector predicate</a> to exclude such potentially-dangerous links,
  or using a <a href=#document-rule-url-pattern-predicate id=speculative-loading-injected-content:document-rule-url-pattern-predicate>document rule URL pattern predicate</a> to allowlist known-safe links, are
  useful techniques in this regard.</p>

  <p>As with all uses of the <code id=speculative-loading-injected-content:the-script-element><a href=scripting.html#the-script-element>script</a></code> element, developers need to be cautious about
  inserting user-provided content into <code>&lt;script type=speculationrules></code>'s
  <a id=speculative-loading-injected-content:child-text-content href=https://dom.spec.whatwg.org/#concept-child-text-content data-x-internal=child-text-content>child text content</a>. In particular, the insertion of an unescaped closing <code>&lt;/script></code> tag could be used to break out of the <code id=speculative-loading-injected-content:the-script-element-2><a href=scripting.html#the-script-element>script</a></code> element
  context and inject attacker-controlled markup.</p>

  <p>The <code>&lt;script type=speculationrules></code> feature causes activity in
  response to content found in the document, so it is worth considering the options open to an
  attacker able to inject unescaped HTML. Such an attacker is already able to inject JavaScript or
  <code id=speculative-loading-injected-content:the-iframe-element><a href=iframe-embed-object.html#the-iframe-element>iframe</a></code> elements. Speculative loads are generally less dangerous than arbitrary script
  execution. However, the use of <a href=#document-rule-predicate id=speculative-loading-injected-content:document-rule-predicate-2>document rule
  predicates</a> could be used to speculatively load links in the document, and the existence of
  those loads could provide a vector for exfiltrating information about those links.
  Defense-in-depth against this possibility is provided by Content Security Policy. In particular,
  the <code>script-src</code> directive can be used to restrict the parsing of speculation
  rules <code id=speculative-loading-injected-content:the-script-element-3><a href=scripting.html#the-script-element>script</a></code> elements, and the <code>default-src</code> directive applies
  to navigational prefetch requests arising from such speculation rules. Additional defense is
  provided by the requirement that speculative loads are only performed to <a href=https://w3c.github.io/webappsec-secure-contexts/#potentially-trustworthy-url id=speculative-loading-injected-content:is-url-potentially-trustworthy data-x-internal=is-url-potentially-trustworthy>potentially-trustworthy URLs</a>, so an on-path attacker would only
  have access to metadata and traffic analysis, and could not see the URLs directly.
  <a href=references.html#refsCSP>[CSP]</a></p>

  <p>It's generally not expected that user-generated content will be added as arbitrary response
  headers: server operators are already going to encounter significant trouble if this is possible.
  It is therefore unlikely that the `<code id=speculative-loading-injected-content:speculation-rules-2><a href=#speculation-rules-2>Speculation-Rules</a></code>` header meaningfully expands the
  XSS attack surface. For this reason, Content Security Policy does not apply to the loading of rule
  sets via that header.</p>


  <h5 id=speculative-loading-ip-anonymization><span class=secno>7.6.5.3</span> IP anonymization<a href=#speculative-loading-ip-anonymization class=self-link></a></h5>

  <p>This standard allows developers to request that navigational prefetches are performed using IP
  anonymization technology provided by the user agent. The details of this anonymization are not
  specified, but some general security principles apply.</p>

  <p>To the extent IP anonymization is implemented using a proxy service, it is advisable to
  minimize the information available to the service operator and other entities on the network path.
  This likely involves, at a minimum, the use of TLS for the connection.</p>

  <p>Site operators need to be aware that, similar to virtual private network (VPN) technology, the
  client IP address seen by the HTTP server might not exactly correspond to the user's actual
  network provider or location, and a traffic for multiple distinct subscribers could originate from
  a single client IP address. This can affect site operators' security and abuse prevention
  measures. IP anonymization measures might make an effort to use an egress IP address which has a
  similar geolocation or is located in the same jurisdiction as the user, but any such behavior is
  particular to the user agent and not guaranteed.</p>


  <h4 id=speculative-loading-privacy><span class=secno>7.6.6</span> Privacy considerations<a href=#speculative-loading-privacy class=self-link></a></h4>


  <h5 id=speculative-loading-heuristics><span class=secno>7.6.6.1</span> Heuristics and optionality<a href=#speculative-loading-heuristics class=self-link></a></h5>

  <p>The <a href=#consider-speculative-loads id=speculative-loading-heuristics:consider-speculative-loads>consider speculative loads</a> algorithm contains a crucial "may" step, which
  encourages user agents to <a href=https://wicg.github.io/nav-speculation/prefetch.html#start-a-referrer-initiated-navigational-prefetch id=speculative-loading-heuristics:start-a-referrer-initiated-navigational-prefetch data-x-internal=start-a-referrer-initiated-navigational-prefetch>start
  referrer-initiated navigational prefetches</a> based on a combination of the <a href=#speculation-rule-eagerness id=speculative-loading-heuristics:speculation-rule-eagerness>speculation
  rule eagerness</a> and other features of the user's environment. Because it can be observable
  to the document whether speculative loads are performed, user agents must take care to protect
  privacy when making such decisions—for instance by only using information which is already
  available to the origin. If these heuristics depend on any persistent state, that state must be
  erased whenever the user erases other site data. If the user agent automatically clears other site
  data from time to time, it must erase such persistent state at the same time.</p>

  <p class=note>The use of <a id=speculative-loading-heuristics:concept-origin href=browsers.html#concept-origin>origin</a> instead of <a id=speculative-loading-heuristics:site href=browsers.html#site>site</a> here is intentional.
  Although same-site origins are generally allowed to coordinate if they wish, the web's security
  model is premised on preventing origins from accessing the data of other origins, even same-site
  ones. Thus, the user agent needs to be sure not to leak such data unintentionally across origins,
  not just across sites.</p>

  <p>Examples of inputs which would be already known to the document:</p>

  <ul><li><p>author-supplied <a href=#speculation-rule-eagerness id=speculative-loading-heuristics:speculation-rule-eagerness-2>eagerness</a><li><p>order of appearance in the document<li><p>whether a link is in the viewport<li><p>whether the cursor is near a link<li><p>rendered size of a link</ul>

  <p>Examples of persistent data related to the origin (which the origin could have gathered itself)
  but which must be erased according to user intent:</p>

  <ul><li><p>whether the user has clicked this or similar links on this document or other documents on
   the same origin</ul>

  <p>Examples of device information which might be valuable in deciding whether speculative loading
  is appropriate, but which needs to be considered as part of the user agent's overall privacy
  posture because it can make the user more identifiable across origins:</p>

  <ul><li><p>coarse device class (CPU, memory)<li><p>coarse battery level<li><p>whether the network connection is known to be metered<li><p>any user-toggleable settings, such as a speculative loading toggle, a battery-saver
   toggle, or a data-saver toggle</ul>


  <h5 id=speculative-loading-state-partitioning><span class=secno>7.6.6.2</span> State partitioning<a href=#speculative-loading-state-partitioning class=self-link></a></h5>

  <p>The <a id=speculative-loading-state-partitioning:start-a-referrer-initiated-navigational-prefetch href=https://wicg.github.io/nav-speculation/prefetch.html#start-a-referrer-initiated-navigational-prefetch data-x-internal=start-a-referrer-initiated-navigational-prefetch>start a referrer-initiated navigational prefetch</a> algorithm is designed to
  ensure that the HTTP requests that it issues behave consistently with how user agents partition
  <a id=speculative-loading-state-partitioning:credentials href=https://fetch.spec.whatwg.org/#credentials data-x-internal=credentials>credentials</a> according to <a href=https://storage.spec.whatwg.org/#storage-key id=speculative-loading-state-partitioning:storage-key data-x-internal=storage-key>storage keys</a>. This
  property is maintained even for cross-partition prefetches, as follows.</p>

  <p>If a future navigation using a prefetched response would load a document in the same partition,
  then at prefetch time, the partitioned credentials can be sent, as they can with subresource
  requests and scripted fetches. If such a future navigation would instead load a document in
  another partition, it would be inconsistent with the partitioning scheme to use partitioned
  credentials for the destination partition (since this would cross the boundary between partitions
  without a top-level navigation) and also inconsistent to use partitioned credentials within the
  originating partition (since this would result in the user seeing a document with different state
  than a non-prefetched navigation). Instead, a third, initially empty, partition is used for such
  requests. These requests therefore send along no credentials from either partition. However, the
  resulting prefetched response body constructed using this initially-empty partition can only be
  used if, at activation time, the destination partition contains no credentials.</p>

  <p>This is somewhat similar to the behavior of only sending such prefetch requests if the
  destination partition is known ahead of time to not contain credentials. However, to avoid such
  behavior being used a way of probing for the presence of credentials, instead such prefetch
  requests are always completed, and in the case of conflicting credentials, their results are not
  used.</p>

  <p>Redirects are possible between these two types of requests. A redirect from a same- to
  cross-partition URL could contain information derived from partitioned credentials in the
  originating partition; however, this is equivalent to the originating document fetching the
  same-partition URL itself and then issuing a request for the cross-partition URL. A redirect from
  a cross- to same-origin URL could carry credentials from the isolated partition, but since this
  partition has no prior state this does not enable tracking based on the user's prior browsing
  activity on that site, and the document could construct the same state by issuing uncredentialed
  requests itself.</p>


  <h5 id=speculative-loading-identity-joining><span class=secno>7.6.6.3</span> Identity joining<a href=#speculative-loading-identity-joining class=self-link></a></h5>

  <p>Speculative loads provide a mechanism through which HTTP requests for later top-level
  navigation can be made without a user gesture. It is natural to ask whether it is possible for two
  coordinating sites to connect user identities.</p>

  <p>Since existing <a id=speculative-loading-identity-joining:credentials href=https://fetch.spec.whatwg.org/#credentials data-x-internal=credentials>credentials</a> for the destination site are not sent (as explained in
  the previous section), that site is limited in its ability to identify the user before navigation
  in a similar way to if the referrer site had simply used <code id=speculative-loading-identity-joining:fetch()><a data-x-internal=fetch() href=https://fetch.spec.whatwg.org/#dom-global-fetch>fetch()</a></code> to make an
  uncredentialed request. Upon navigation, this becomes similar to ordinary navigation (e.g., by
  clicking a link that was not speculatively loaded).</p>

  <p>To the extent that user agents attempt to mitigate identity joining for ordinary fetches and
  navigations, they can apply similar mitigations to speculatively-loaded navigations.</p>


  <h3 id=the-x-frame-options-header><span class=secno>7.7</span> The `<code id=the-x-frame-options-header:x-frame-options><a href=#x-frame-options>X-Frame-Options</a></code>` header<a href=#the-x-frame-options-header class=self-link></a></h3><div class="mdn-anno wrapped"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options title="The X-Frame-Options HTTP response header can be used to indicate whether or not a browser should be allowed to render a page in a <frame>, <iframe>, <embed> or <object>. Sites can use this to avoid click-jacking attacks, by ensuring that their content is not embedded into other sites.">Headers/X-Frame-Options</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>4+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>4+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.5+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>8+</span></span><hr><span class="firefox_android yes"><span>Firefox Android</span><span>Yes</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>Yes</span></span><span class="chrome_android yes"><span>Chrome Android</span><span>Yes</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div>

  <p>The `<dfn id=x-frame-options data-dfn-type=http-header><code>X-Frame-Options</code></dfn>` HTTP response header is a way
  of controlling whether and how a <code id=the-x-frame-options-header:document><a href=dom.html#document>Document</a></code> may be loaded inside of a <a id=the-x-frame-options-header:child-navigable href=document-sequences.html#child-navigable>child
  navigable</a>. For sites using CSP, the <code id=the-x-frame-options-header:frame-ancestors-directive><a data-x-internal=frame-ancestors-directive href=https://w3c.github.io/webappsec-csp/#frame-ancestors>frame-ancestors</a></code> directive provides more granular control over the
  same situations. It was originally defined in <cite>HTTP Header Field X-Frame-Options</cite>, but
  the definition and processing model here supersedes that document.
  <a href=references.html#refsCSP>[CSP]</a> <a href=references.html#refsRFC7034>[RFC7034]</a>

  <p class=note>In particular, <cite>HTTP Header Field X-Frame-Options</cite> specified an `<code>ALLOW-FROM</code>` variant of the header, but that is not to be implemented.</p>

  <p class=note>Per the below processing model, if both
  a CSP <code id=the-x-frame-options-header:frame-ancestors-directive-2><a data-x-internal=frame-ancestors-directive href=https://w3c.github.io/webappsec-csp/#frame-ancestors>frame-ancestors</a></code> directive and an
  `<code id=the-x-frame-options-header:x-frame-options-2><a href=#x-frame-options>X-Frame-Options</a></code>` header are used in the same <a href=https://fetch.spec.whatwg.org/#concept-response id=the-x-frame-options-header:concept-response data-x-internal=concept-response>response</a>, then `<code id=the-x-frame-options-header:x-frame-options-3><a href=#x-frame-options>X-Frame-Options</a></code>` is ignored.</p>

  <p>For web developers and conformance checkers, its value <a href=https://fetch.spec.whatwg.org/#abnf id=the-x-frame-options-header:header-abnf data-x-internal=header-abnf>ABNF</a>
  is:</p>

  <pre><code class='abnf'><c- nc>X-Frame-Options</c-> <c- o>=</c-> <c- l>&quot;DENY&quot;</c-> <c- o>/</c-> <c- l>&quot;SAMEORIGIN&quot;</c-></code></pre>

  

  <p>To <dfn id="check-a-navigation-response's-adherence-to-x-frame-options">check a navigation response's adherence to `<code>X-Frame-Options</code>`</dfn>, given
  a <a href=https://fetch.spec.whatwg.org/#concept-response id=the-x-frame-options-header:concept-response-2 data-x-internal=concept-response>response</a> <var>response</var>, a <a id=the-x-frame-options-header:navigable href=document-sequences.html#navigable>navigable</a>
  <var>navigable</var>, a <a href=https://w3c.github.io/webappsec-csp/#csp-list id=the-x-frame-options-header:concept-csp-list data-x-internal=concept-csp-list>CSP list</a> <var>cspList</var>, and
  an <a id=the-x-frame-options-header:concept-origin href=browsers.html#concept-origin>origin</a> <var>destinationOrigin</var>:</p>

  <ol><li><p>If <var>navigable</var> is not a <a id=the-x-frame-options-header:child-navigable-2 href=document-sequences.html#child-navigable>child navigable</a>, then return true.<li>
    <p><a href=https://infra.spec.whatwg.org/#list-iterate id=the-x-frame-options-header:list-iterate data-x-internal=list-iterate>For each</a> <var>policy</var> of <var>cspList</var>:</p>

    <ol><li><p>If <var>policy</var>'s <a href=https://w3c.github.io/webappsec-csp/#policy-disposition id=the-x-frame-options-header:csp-disposition data-x-internal=csp-disposition>disposition</a> is not "<code>enforce</code>", then <a id=the-x-frame-options-header:continue href=https://infra.spec.whatwg.org/#iteration-continue data-x-internal=continue>continue</a>.<li><p>If <var>policy</var>'s <a href=https://w3c.github.io/webappsec-csp/#policy-directive-set id=the-x-frame-options-header:csp-directive-set data-x-internal=csp-directive-set>directive set</a> <a href=https://infra.spec.whatwg.org/#list-contain id=the-x-frame-options-header:list-contains data-x-internal=list-contains>contains</a> a <code id=the-x-frame-options-header:frame-ancestors-directive-3><a data-x-internal=frame-ancestors-directive href=https://w3c.github.io/webappsec-csp/#frame-ancestors>frame-ancestors</a></code> directive, then return true.</ol>
   <li><p>Let <var>rawXFrameOptions</var> be the result of <a href=https://fetch.spec.whatwg.org/#concept-header-list-get-decode-split id=the-x-frame-options-header:concept-header-list-get-decode-split data-x-internal=concept-header-list-get-decode-split>getting, decoding, and splitting</a>
   `<code id=the-x-frame-options-header:x-frame-options-4><a href=#x-frame-options>X-Frame-Options</a></code>` from <var>response</var>'s <a href=https://fetch.spec.whatwg.org/#concept-response-header-list id=the-x-frame-options-header:concept-response-header-list data-x-internal=concept-response-header-list>header list</a>.<li><p>Let <var>xFrameOptions</var> be a new <a id=the-x-frame-options-header:set href=https://infra.spec.whatwg.org/#ordered-set data-x-internal=set>set</a>.<li><p><a href=https://infra.spec.whatwg.org/#list-iterate id=the-x-frame-options-header:list-iterate-2 data-x-internal=list-iterate>For each</a> <var>value</var> of
   <var>rawXFrameOptions</var>, <a href=https://infra.spec.whatwg.org/#set-append id=the-x-frame-options-header:set-append data-x-internal=set-append>append</a> <var>value</var>,
   <a id=the-x-frame-options-header:converted-to-ascii-lowercase href=https://infra.spec.whatwg.org/#ascii-lowercase data-x-internal=converted-to-ascii-lowercase>converted to ASCII lowercase</a>, to <var>xFrameOptions</var>.<li>
    <p>If <var>xFrameOptions</var>'s <a href=https://infra.spec.whatwg.org/#list-size id=the-x-frame-options-header:list-size data-x-internal=list-size>size</a> is greater than 1, and
    <var>xFrameOptions</var> <a href=https://infra.spec.whatwg.org/#list-contain id=the-x-frame-options-header:list-contains-2 data-x-internal=list-contains>contains</a> any of "<code>deny</code>", "<code>allowall</code>", or "<code>sameorigin</code>", then return false.</p>

    <p class=note>The intention here is to block any attempts at applying
    `<code id=the-x-frame-options-header:x-frame-options-5><a href=#x-frame-options>X-Frame-Options</a></code>` which were trying to do something valid, but appear confused.</p>

    <p class=note>This is the only impact of the legacy `<code>ALLOWALL</code>` value
    on the processing model.</p>
   <li>
    <p>If <var>xFrameOptions</var>'s <a href=https://infra.spec.whatwg.org/#list-size id=the-x-frame-options-header:list-size-2 data-x-internal=list-size>size</a> is greater than 1, then
    return true.</p>

    <p class=note>This means it contains multiple invalid values, which we treat the same way as
    if the header was omitted entirely.</p>
   <li><p>If <var>xFrameOptions</var>[0] is "<code>deny</code>", then return
   false.<li>
    <p>If <var>xFrameOptions</var>[0] is "<code>sameorigin</code>", then:</p>

    <ol><li><p>Let <var>containerDocument</var> be <var>navigable</var>'s <a href=document-sequences.html#nav-container-document id=the-x-frame-options-header:nav-container-document>container document</a>.<li>
      <p><a id=the-x-frame-options-header:while href=https://infra.spec.whatwg.org/#iteration-while data-x-internal=while>While</a> <var>containerDocument</var> is not null:</p>

      <ol><li><p>If <var>containerDocument</var>'s <a href=https://dom.spec.whatwg.org/#concept-document-origin id=the-x-frame-options-header:concept-document-origin data-x-internal=concept-document-origin>origin</a>
       is not <a id=the-x-frame-options-header:same-origin href=browsers.html#same-origin>same origin</a> with <var>destinationOrigin</var>, then return
       false.<li><p>Set <var>containerDocument</var> to <var>containerDocument</var>'s <a href=document-sequences.html#doc-container-document id=the-x-frame-options-header:doc-container-document>container document</a>.</ol>
     </ol>
   <li>
    <p>Return true.</p>

    <p class=note>If we've reached this point then we have a lone invalid value (which could
    potentially be one the legacy `<code>ALLOWALL</code>` or `<code>ALLOW-FROM</code>` forms). These are treated as if the header were omitted
    entirely.</p>
   </ol>

  <hr>

  

  <div class=example>
   <p>The following table illustrates the processing of various values for the header, including
   non-conformant ones:</p>

   <table class=data><thead><tr><th>`<code id=the-x-frame-options-header:x-frame-options-6><a href=#x-frame-options>X-Frame-Options</a></code>`<th>Valid<th>Result<tbody><tr><td>`<code>DENY</code>`<td>✅<td>embedding disallowed<tr><td>`<code>SAMEORIGIN</code>`<td>✅<td>same-origin embedding allowed<tr><td>`<code>INVALID</code>`<td>❌<td>embedding allowed<tr><td>`<code>ALLOWALL</code>`<td>❌<td>embedding allowed<tr><td>`<code>ALLOW-FROM=https://example.com/</code>`<td>❌<td>embedding allowed (from anywhere)</table>
  </div>

  <div class=example>
   <p>The following table illustrates how various non-conformant cases involving multiple values are
   processed:</p>

   <table class=data><thead><tr><th>`<code id=the-x-frame-options-header:x-frame-options-7><a href=#x-frame-options>X-Frame-Options</a></code>`<th>Result<tbody><tr><td>`<code>SAMEORIGIN, SAMEORIGIN</code>`<td>same-origin embedding allowed<tr><td>`<code>SAMEORIGIN, DENY</code>`<td>embedding disallowed<tr><td>`<code>SAMEORIGIN,</code>`<td>embedding disallowed<tr><td>`<code>SAMEORIGIN, ALLOWALL</code>`<td>embedding disallowed<tr><td>`<code>SAMEORIGIN, INVALID</code>`<td>embedding disallowed<tr><td>`<code>ALLOWALL, INVALID</code>`<td>embedding disallowed<tr><td>`<code>ALLOWALL,</code>`<td>embedding disallowed<tr><td>`<code>INVALID, INVALID</code>`<td>embedding allowed</table>

   <p>The same results are obtained whether the values are delivered in a single header whose value is comma-delimited,
   or in multiple headers.</p>
  </div>


  <h3 id=the-refresh-header><span class=secno>7.8</span> The `<code id=the-refresh-header:refresh><a href=#refresh>Refresh</a></code>` header<a href=#the-refresh-header class=self-link></a></h3>

  <p>The `<dfn id=refresh data-dfn-type=http-header><code>Refresh</code></dfn>` HTTP response header is the HTTP-equivalent
  to a <code id=the-refresh-header:the-meta-element><a href=semantics.html#the-meta-element>meta</a></code> element with an <code id=the-refresh-header:attr-meta-http-equiv><a href=semantics.html#attr-meta-http-equiv>http-equiv</a></code>
  attribute in the <a href=semantics.html#attr-meta-http-equiv-refresh id=the-refresh-header:attr-meta-http-equiv-refresh>Refresh state</a>. It takes <a href=semantics.html#conformance-attr-meta-http-equiv-refresh>the same value</a> and works largely the
  same. Its processing model is detailed in <a href=document-lifecycle.html#initialise-the-document-object id=the-refresh-header:initialise-the-document-object>create and initialize a <code>Document</code>
  object</a>.</p>
  


  <h3 id=nav-traversal-ui><span class=secno>7.9</span> <span id=history-notes></span>Browser user interface
  considerations<a href=#nav-traversal-ui class=self-link></a></h3>

  <p>Browser user agents should provide the ability to <a id=nav-traversal-ui:navigate href=browsing-the-web.html#navigate>navigate</a>, <a id=nav-traversal-ui:reload href=browsing-the-web.html#reload>reload</a>, and <a href=document-lifecycle.html#nav-stop id=nav-traversal-ui:nav-stop>stop loading</a>
  any <a id=nav-traversal-ui:top-level-traversable href=document-sequences.html#top-level-traversable>top-level traversable</a> in their <a id=nav-traversal-ui:top-level-traversable-set href=document-sequences.html#top-level-traversable-set>top-level traversable set</a>.</p>

  <p class=example>For example, via a location bar and reload/stop button UI.</p>

  <p>Browser user agents should provide the ability to <a href=browsing-the-web.html#traverse-the-history-by-a-delta id=nav-traversal-ui:traverse-the-history-by-a-delta>traverse by a delta</a> any <a id=nav-traversal-ui:top-level-traversable-2 href=document-sequences.html#top-level-traversable>top-level traversable</a> in their <a id=nav-traversal-ui:top-level-traversable-set-2 href=document-sequences.html#top-level-traversable-set>top-level
  traversable set</a>.</p>

  <p class=example>For example, via back and forward buttons, possibly including long-press
  abilities to change the delta.</p>

  <p>It is suggested that such user agents allow traversal by deltas greater than one, to avoid
  letting a page "trap" the user by stuffing the session history with spurious entries. (For
  example, via repeated calls to <code id=nav-traversal-ui:dom-history-pushstate><a href=nav-history-apis.html#dom-history-pushstate>history.pushState()</a></code> or
  <a href=browsing-the-web.html#navigate-fragid id=nav-traversal-ui:navigate-fragid>fragment navigations</a>.)</p>

  <p class=note>Some user agents have heuristics for translating a single "back" or "forward"
  button press into a larger delta, specifically to overcome such abuses. We are contemplating
  specifying these heuristics in <a href=https://github.com/whatwg/html/issues/7832>issue
  #7832</a>.</p>

  <p>Browser user agents should offer users the ability to <a id=nav-traversal-ui:create-a-fresh-top-level-traversable href=document-sequences.html#create-a-fresh-top-level-traversable>create a fresh top-level
  traversable</a>, given a user-provided or user agent-determined initial <a id=nav-traversal-ui:url href=https://url.spec.whatwg.org/#concept-url data-x-internal=url>URL</a>.</p>

  <p class=example>For example, via a "new tab" or "new window" button.</p>

  <p>Browser user agents should offer users the ability to arbitrarily <a href=document-sequences.html#close-a-top-level-traversable id=nav-traversal-ui:close-a-top-level-traversable>close</a> any <a id=nav-traversal-ui:top-level-traversable-3 href=document-sequences.html#top-level-traversable>top-level traversable</a> in their
  <a id=nav-traversal-ui:top-level-traversable-set-3 href=document-sequences.html#top-level-traversable-set>top-level traversable set</a>.</p>

  <p class=example>For example, by clicking a "close tab" button.</p>

  <hr>

  <p>Browser user agents may provide ways for the user to explicitly cause any
  <a id=nav-traversal-ui:navigable href=document-sequences.html#navigable>navigable</a> (not just a <a id=nav-traversal-ui:top-level-traversable-4 href=document-sequences.html#top-level-traversable>top-level traversable</a>) to <a id=nav-traversal-ui:navigate-2 href=browsing-the-web.html#navigate>navigate</a>, <a id=nav-traversal-ui:reload-2 href=browsing-the-web.html#reload>reload</a>, or <a href=document-lifecycle.html#nav-stop id=nav-traversal-ui:nav-stop-2>stop
  loading</a>.</p>

  <p class=example>For example, via a context menu.</p>

  <p>Browser user agents may provide the ability for users to <a id=nav-traversal-ui:destroy-a-top-level-traversable href=document-sequences.html#destroy-a-top-level-traversable>destroy a top-level
  traversable</a>.</p>

  <p class=example>For example, by force-closing a window containing one or more such <a href=document-sequences.html#top-level-traversable id=nav-traversal-ui:top-level-traversable-5>top-level traversables</a>.</p>

  <hr>

  <p>When a user requests a <a id=nav-traversal-ui:reload-3 href=browsing-the-web.html#reload>reload</a> of a <a id=nav-traversal-ui:navigable-2 href=document-sequences.html#navigable>navigable</a> whose <a href=document-sequences.html#nav-active-history-entry id=nav-traversal-ui:nav-active-history-entry>active session history entry</a>'s <a href=browsing-the-web.html#she-document-state id=nav-traversal-ui:she-document-state>document state</a>'s <a href=browsing-the-web.html#document-state-resource id=nav-traversal-ui:document-state-resource>resource</a> is a <a id=nav-traversal-ui:post-resource href=browsing-the-web.html#post-resource>POST resource</a>, the user agent
  should prompt the user to confirm the operation first, since otherwise transactions (e.g.,
  purchases or database modifications) could be repeated.</p>

  <p>When a user requests a <a id=nav-traversal-ui:reload-4 href=browsing-the-web.html#reload>reload</a> of a <a id=nav-traversal-ui:navigable-3 href=document-sequences.html#navigable>navigable</a>, user agents may provide
  a mechanism for ignoring any caches when reloading.</p>

  <hr>

  <p>All calls to <a id=nav-traversal-ui:navigate-3 href=browsing-the-web.html#navigate>navigate</a> initiated by the mechanisms mentioned above must have the <i id=nav-traversal-ui:navigation-user-involvement><a href=browsing-the-web.html#navigation-user-involvement>userInvolvement</a></i> argument set to "<code id=nav-traversal-ui:uni-browser-ui><a href=browsing-the-web.html#uni-browser-ui>browser UI</a></code>".</p>

  <p>All calls to <a id=nav-traversal-ui:reload-5 href=browsing-the-web.html#reload>reload</a> initiated by the mechanisms mentioned above must have the <i id=nav-traversal-ui:reload-user-involvement><a href=browsing-the-web.html#reload-user-involvement>userInvolvement</a></i> argument set to "<code id=nav-traversal-ui:uni-browser-ui-2><a href=browsing-the-web.html#uni-browser-ui>browser UI</a></code>".</p>

  <p>All calls to <a id=nav-traversal-ui:traverse-the-history-by-a-delta-2 href=browsing-the-web.html#traverse-the-history-by-a-delta>traverse the history by a delta</a> initiated by the mechanisms mentioned
  above must not pass a value for the <i id=nav-traversal-ui:traverse-sourcedocument><a href=browsing-the-web.html#traverse-sourcedocument>sourceDocument</a></i>
  argument.</p>

  <hr>

  <p>The above recommendations, and the data structures in this specification, are not meant to
  place restrictions on how user agents represent the session history to the user.</p>

  <p>For example, although a <a id=nav-traversal-ui:top-level-traversable-6 href=document-sequences.html#top-level-traversable>top-level traversable</a>'s <a href=document-sequences.html#tn-session-history-entries id=nav-traversal-ui:tn-session-history-entries>session history entries</a> are stored and maintained as a
  list, and the user agent is recommended to give an interface for <a href=browsing-the-web.html#traverse-the-history-by-a-delta id=nav-traversal-ui:traverse-the-history-by-a-delta-3>traversing that list by a delta</a>, a novel user agent could instead or
  in addition present a tree-like view, with each page having multiple "forward" pages that the user
  can choose between.</p>

  <p>Similarly, although session history for all descendant <a href=document-sequences.html#navigable id=nav-traversal-ui:navigable-4>navigables</a> is stored in their <a id=nav-traversal-ui:traversable-navigable href=document-sequences.html#traversable-navigable>traversable navigable</a>, user
  agents could present the user with a more nuanced per-<a id=nav-traversal-ui:navigable-5 href=document-sequences.html#navigable>navigable</a> view of the session
  history.</p>

  <hr>

  <p>Browser user agents may use a <a id=nav-traversal-ui:top-level-browsing-context href=document-sequences.html#top-level-browsing-context>top-level browsing context</a>'s <a id=nav-traversal-ui:is-popup href=document-sequences.html#is-popup>is
  popup</a> boolean for the following purposes:

  <ul><li><p>Deciding whether or not to provide a minimal web browser user interface for the
   corresponding <a id=nav-traversal-ui:top-level-traversable-7 href=document-sequences.html#top-level-traversable>top-level traversable</a>.<li><p>Performing the optional steps in <a id=nav-traversal-ui:set-up-browsing-context-features href=https://drafts.csswg.org/cssom-view/#set-up-browsing-context-features data-x-internal=set-up-browsing-context-features>set up browsing context features</a>.</ul>

  <p>In both cases user agents might additionally incorporate user preferences, or present a choice
  as to whether to go down the popup route.</p>

  <p>User agents that provide a minimal user interface for such popups are encouraged to not hide
  the browser's location bar.</p>


  <nav><a href=document-lifecycle.html>← 7.5 Document lifecycle</a> — <a href=index.html>Table of Contents</a> — <a href=webappapis.html>8 Web application APIs →</a></nav>
